Update record on database in MVC4 - entity-framework

need some help here..
Aim: Update record on database in MVC4
I have a Accordian view with two buttons #1.Edit #2.save..
Till now what had done is..
using following code i have fetch data from database to corresponding text boxes.
Step 1: Data filled in textboxes are property set as readonly once edit button clicked text boxes will set as editable.
Step 2:if i change data and click save button that should update on database
Problem:
While updating the data in the database updated data is adding in the new row as a new data.
But i need the existing data should be updated
View:
<body>
<div id='cssmenu'>
<ul>
<li class='active'></li>
<li class='has-sub'>
<a href='#'><span>Profile</span></a>
<ul>
<form method="post" >
<table>
<tr>
<td>
#Html.DisplayNameFor(model => model.FirstName)
</td>
<td>
#Html.TextBoxFor(m => m.FirstName, new { #readonly = "readonly" })
#*#Html.EditorFor(model => model.FirstName)*#
#Html.ValidationMessageFor(model => model.FirstName)
</td>
</tr>
<tr>
<td>
#Html.DisplayNameFor(model => model.LastName)
</td>
<td>
#Html.TextBoxFor(m => m.LastName, new { #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.LastName)
</td>
</tr>
<tr>
<td>
#Html.DisplayNameFor(model => model.EmailID)
</td>
<td>
#Html.TextBoxFor(m => m.EmailID, new { #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.EmailID)
</td>
</tr>
<tr>
<td>
#Html.DisplayNameFor(model => model.MobileNumber)
</td>
<td>
#Html.TextBoxFor(m => m.MobileNumber, new { #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.MobileNumber)
</td>
</tr>
</table>
<input type="button" id="btn" name="Edit" value="Edit"/>
<input type="submit" name="Save" id="Save" />
#*<input type="submit" name="Save" value="Save" onclick="location.href='#Url.Action("Save", "CU")'" />*#
</form>
</ul>
</li>
<li class='has-sub'>
<a href='#'><span>Change Password</span></a>
<ul>
<li><a href='#'><span>Company</span></a></li>
<li class='last'><a href='#'><span>Contact</span></a></li>
</ul>
</li>
<li class='has-sub'>
<a href='#'><span>Add Customer</span></a>
<ul>
<li><a href='#'><span>Company</span></a></li>
<li class='last'><a href='#'><span>Contact</span></a></li>
</ul>
</li>
</ul>
</div>
</body>
#section scripts
{
<script type="text/javascript">
$("#btn").click(function () {
$("#FirstName").removeAttr("readonly");
$("#LastName").removeAttr("readonly");
$("#EmailID").removeAttr("readonly");
$("#MobileNumber").removeAttr("readonly");
});
</script>
}
Controller
public ActionResult AccountPanel(int id, string Save, string FirstName)
{
var profile = (from s in db.tblUsers
where s.UserTypeId == 3 && s.UserID == id
select new Profile
{
FirstName = s.FirstName,
LastName = s.LastName,
EmailID = s.EmailID,
MobileNumber = s.MobileNumber
}).FirstOrDefault();
if (Save != null)
{
using (var context = new SYTEntities())
{
var s = context.tblUsers.Where(a => a.UserID == id).FirstOrDefault();
s.FirstName = FirstName;
s.LastName = profile.LastName;
s.EmailID = profile.EmailID;
s.MobileNumber = profile.MobileNumber;
context.tblUsers.Add(s);
context.SaveChanges();
}
}
return View(profile);
}

To update data in the database please change to below code.
if (Save != null)
{
using (var context = new SYTEntities())
{
var s = context.tblUsers.Where(a => a.UserID == id).FirstOrDefault();
s.FirstName = FirstName;
s.LastName = profile.LastName;
s.EmailID = profile.EmailID;
s.MobileNumber = profile.MobileNumber;
context.SaveChanges();
}
}
remove context.tblUsers.Add(s); from your code

using (var context = new SYTEntities())
{
var s = context.tblUsers.Where(a => a.UserID == id).FirstOrDefault();
s.FirstName = FirstName;
s.LastName = profile.LastName;
s.EmailID = profile.EmailID;
s.MobileNumber = profile.MobileNumber;
// SET STATE TO CHANGED
db.Entry(tblUsers).State = EntityState.Modified;
context.SaveChanges();
}

Related

Is there any way to have Controller, ViewModel and View without Model? It's for an Index only view

What I want to do is a parametrized report, i would love to use SSRS or other fancy tools for this but it's sort of dangerous at this point because i don't really want to mess around with the company server and I dont have much time; Also If it's a tool it should be a free and light tool and i didn't find one by now.
So, my idea is making a simple controller with Index that will return a List to View according to parameters and the View will use that ViewModel as Model then the users can export that list to CSV or PDF, the problem is: MVC is asking for a real db model to complete the scaffolding, how can this be done then?
Controller (I call an stored proc here)
public class ReporteEntregasPresentacionController : Controller
{
private EntregaMedicamentosEntities db = new EntregaMedicamentosEntities();
public ActionResult Index(DateTime DateFrom, DateTime DateTo)
{
ReporteEntregasPresentacionViewModel rep = new ReporteEntregasPresentacionViewModel();
string sqlQuery = "[dbo].[spEntregasPorPresentacion] ({0},{1})";
Object[] parameters = { DateFrom, DateTo };
rep.LstEntregasPresentacionViewModel = db.Database.SqlQuery<ItemEntregasPresentacionViewModel>(sqlQuery, parameters).ToList();
return View(rep);
}
}
ViewModel:
public class ReporteEntregasPresentacionViewModel
{
public int index;
public List<ItemEntregasPresentacionViewModel> LstEntregasPresentacionViewModel;
}
public class ItemEntregasPresentacionViewModel {
public string idProducto { get; set; }
public string Descripcion { get; set; }
public string EntregasTotales { get; set; }
}
I don't have a View now but i should be something like this:
#model EntregaMedicamentos.Models.ReporteEntregasPresentacionViewModel
<link href="~/Content/css/styles.css" rel="stylesheet" />
#{
ViewBag.Title = "ReporteEntregasPresentacion";
}
<h2>ReporteEntregasPresentacion</h2>
#using (Html.BeginForm("Index", "Entrega", FormMethod.Post))
{
<div class="card text-white bg-secondary">
<h5 class="card-header">Search</h5>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="input-group">
#Html.TextBox("DateFrom", ViewBag.currentFilter1 as DateTime?, new { #class = "form-control", placeholder = "Desde fecha", #readonly = "true", type = "datetime" })
#Html.TextBox("DateTo", ViewBag.currentFilter2 as DateTime?, new { #class = "form-control", placeholder = "Hasta fecha", #readonly = "true", type = "datetime" })
<button id="Submit4" type="submit" style='font-size:22px ;color:blue'><i class='fas fa-search'></i></button>
</div>
</div>
</div>
</div>
</div>
}
<br>
<table class="table table-striped ">
<tr class="table-primary">
<th>
Código
</th>
<th>
Producto
</th>
<th>
Entregas Totales
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.idProducto)
</td>
<td>
#Html.DisplayFor(modelItem => item.Descripcion)
</td>
<td>
#Html.DisplayFor(modelItem => item.Valor)
</td>
</tr>
}
</table>
I ended up creating a real table/model and then it worked fine with the viewmodel. Thanks.

Update partialview after Model updaton using Model popup

I have index page which contains 2 partial views.One for displaying Roles and another for displaying corresponding privileges.
#model IEnumerable<sample.Models.Role_Privilege_Map>
#{
ViewBag.Title = "RolePrivilgeMapping";
}
<h2>RolePrivilgeMapping</h2>
<script>
$(document).ready(function () {
registerTableClick();
//$("#tblRole tbody tr:first").trigger();
});
function registerTableClick() {
$("#tblRole tbody tr").on("click", function () {
$(this).siblings().removeClass('selected_row');
$(this).addClass("selected_row");
var roleId = parseInt($(this).find("td:eq(0)").text());
loadPrivilege(roleId);
});
function loadtrackPrivilege(roleId) {
$("#PrivilegeWrapper").load("#Url.Action("PrivilegesPartial", "RolePrivilegeMapping")",
{ 'roleID': roleId },
function (response, status, xhr) {
if (status == "error") {
alert("An error occurred while loading privileges.");
}
});
}
}
</script>
<div id="RolePrivilgeMappingWrapper">
<div class="float-left" id="roleWrapper">
#Html.Partial("_Role", sample.Models.DataProvider.DataProvider.GetRoleNames())
</div>
<div class="float-left" id="PrivilegeWrapper">
#Html.Partial("_Privilege", sample.Models.DataProvider.Provider.GetPrivilegeNames())
</div>
</div>
Here is my _Role.cshtml
#model IEnumerable<sample.Models.webpages_Roles>
#{
ViewBag.Title = "Index";
}
<script type="text/ecmascript">
$(document).ready(function () {
$.ajaxSetup({ cache: false });
$(".editDialog").live("click", function (e) {
var url = $(this).attr('href');
$("#dialog-edit").dialog({
title: 'Edit Role',
autoOpen: false,
resizable: false,
height: 255,
width: 400,
show: { effect: 'drop', direction: "up" },
modal: true,
draggable: true,
open: function (event, ui) {
$(this).load(url);
},
close: function (event, ui) {
$(this).dialog('close');
}
});
$("#dialog-edit").dialog('open');
return false;
});
});
</script>
<div class="settingsTable" style="position: relative; width: 100%; margin: 0 auto">
<div style="width: 50%; margin: 0 auto">
<div style="width: 50%; margin: 0 auto">
<h2>Role</h2>
</div>
</div>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table id="tblRole">
<tr>
<th>
#Html.DisplayNameFor(model => model.RoleId)
</th>
<th>
#Html.DisplayNameFor(model => model.RoleName)
</th>
<th>Action</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.RoleId)
</td>
<td>
#Html.DisplayFor(modelItem => item.RoleName)
</td>
<td>
#Html.ActionLink("Edit", "OpenEditRoleDialog", "RolePrivilegeMapping", new { id = item.RoleId }, new { #class="editDialog"}) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</table>
<div id="dialog-edit" style="display: none">
</div>
</div>
On Role partial view I have edit link for every row displayed.
here is my _editrole.cshtml
#model sample.Models.webpages_Roles
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Ajax.BeginForm("EditRole", "RolePrivilegeMapping", new AjaxOptions { HttpMethod = "POST" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>webpages_Roles</legend>
#Html.HiddenFor(model => model.RoleId)
<div class="editor-label">
#Html.LabelFor(model => model.RoleName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.RoleName)
#Html.ValidationMessageFor(model => model.RoleName)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
Now while I click on edit link a jquery modal box gets displayed for editing details.I submit the changes asychronously as
#using (Ajax.BeginForm("EditRole", "RolePrivilegeMapping", new AjaxOptions { HttpMethod = "POST" }))
And the edit method is
public ActionResult EditRole(webpages_Roles webpages_roles)
{
if (ModelState.IsValid)
{
db.Entry(webpages_roles).State = EntityState.Modified;
db.SaveChanges();
}
return View("index");
}
My problem is
1. The dialog box is not getting closed. I have to manually click the cross
bar.
2. The Role partial view is not getting updated until I have to refresh the page.
I followed this link http://www.mindstick.com/Articles/279bc324-5be3-4156-a9e9-dd91c971d462/CRUD%20operation%20using%20Modal%20dialog%20in%20ASP%20NET%20MVC#.VVlyBLmqpHx

Button redirecting to the grid page

I have a custom module 'banner' and in which I have added a button in its second tab(only two tabs for the module). when click on that button, it is submitting my banner automatically and then go to the grid page(i e it acts as just another save button). But the function of this button is to add an uploading image field.ie whenever the button is clicked, it should add an image form field to my tab file. This is my tab file.
<?php
class Karaokeshop_Banner_Block_Adminhtml_Banner_Edit_Tab_Image extends Mage_Adminhtml_Block_Widget_Form
{
protected function _prepareForm()
{
$form = new Varien_Data_Form();
$this->setForm($form);
$fieldset = $form->addFieldset('banner_image', array('legend'=>Mage::helper('banner')->__('Banner Image')));
//declaring a new custom form field and adding
$fieldset->addType('add_button', 'Karaokeshop_Banner_Block_Adminhtml_Banner_Edit_Tab_Field_Custom');
$fieldset->addField('banner_img_add_button', 'add_button', array(
'title' => Mage::helper('banner')->__('Add Banner Image'),
'id' => 'add_banner_img_button',
'class' => 'scalable save',
'style' => '',
'onclick' => 'banner.add(this)',
'type' => 'button',
));
return parent::_prepareForm();
}
}
this is my button defining file
<?php
class Karaokeshop_Banner_Block_Adminhtml_Banner_Edit_Tab_Field_Custom extends Varien_Data_Form_Element_Abstract
{
public function __construct($attributes=array())
{
parent::__construct($attributes);
}
public function getElementHtml()
{
$value = $this->getTitle();
$onclick=$this->getOnclick();
$class=$this->getClass();
$id=$this->getId();
$style=$this->getStyle();
$type=$this->getType();
$html='<button id="'.$id.'" class="'.$class.'" style="'.$style.'" onclick="'.$onclick.'" type="'.$type.'" title="'.$value.'">'.$value.' </button>';
$html .= '<p id="' . $this->getHtmlId() . '"'. $this->serialize($this->getHtmlAttributes()) .'>
<script type="text/javascript">
//<![CDATA[
var banner =
{
add : function(obj)
{
},
};
//]]>
</script>
</p>';
return $html;
}
}
what should i do to change my button to an add button? what should I do to avoid this submitting functionality of the button. Please help me. Thanks in advance
First you need to call your phtml from block like this :
class My_Moudles_Block_Adminhtml_Image_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form
{
public function __construct()
{
parent::__construct();
$this->setTemplate('modules/imageupload.phtml');
$this->setFormAction(Mage::getUrl('*/*/imageupload'));
}
then create file in adminhtml/default/default/template/yourmodule/imageupload.phtml and put this code there.
<div class="entry-edit">
<div class="entry-edit-head">
<h4 class="icon-head head-edit-form fieldset-legend"><?php echo $this->__('General')?></h4>
<div class="form-buttons"></div>
</div>
<form id="imageform" method="post" action="<? echo $this->getFormAction(); ?>">
<div id="rules_form" class="fieldset ">
<div class="hor-scroll">
<table cellspacing="0" class="form-list">
<tbody>
<tr>
<td class="label"><?php echo $this->__('Add Image')?></td>
<td class="grid tier" colspan="10">
<table cellspacing="0" id="chain_tiers" class="chain border" style=" width:465px; ">
<thead>
<tr class="headings">
<th><?php echo $this->__('Image')?></th>
<th class="last"><?php echo $this->__('Action')?></th>
</tr>
<tr class="template no-display" id="email_chain_add_template">
<td class="nobr">
<input type="file" id="chain_Image" value="0" name="imageg" class="requried-entry input-text">
</td>
<td class="last"><input type="hidden" value="" disabled="no-template" class="delete" name="email_chain[__index__][delete]"><button onclick="emailsControl.deleteItem(event);return false" class="scalable delete icon-btn delete-product-option" title="Delete Image"><span><?php echo $this->__('Delete')?></span></button></td>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
<td class="a-right" colspan="6">
<button style="" onclick="emailsControl.addItem()" class="scalable add" type="button" title="Add email" id="id"><span><span><span><?php echo $this->__('Add Image')?></span></span></span></button></td>
</tr>
</tfoot>
<tbody id="email_chain_container">
<tr>
<td class="nobr">
<input type="file" id="chain_Image" value="" name="Image[]" class="input-text">
</td>
<td class="last"><input type="hidden" value="" class="delete" name="email_chain[delete][]"><button onclick="emailsControl.deleteItem(event);return false" class="scalable delete icon-btn delete-product-option" title="Delete Image"><span><?php echo $this->__('Delete')?></span></button></td>
</tr>
</tbody>
</table>
<script type="text/javascript">
//<![Cchain[
var emailsControl = {
itemsCount : 0,
deleteButton : false,
addItem : function () {
var chain = {};
chain.TEMPLATE_ID = 0;
chain.index = this.itemsCount++;
if (arguments.length == 1) {
chain.TEMPLATE_ID = arguments[0];
}
var s = '<tr>' + $('email_chain_add_template').innerHTML.replace(/__index__/g, '#{index}').replace(/\sdisabled="?no-template"?/g, ' ').replace(/disabled/g, ' ').replace(/="'([^']*)'"/g, '="$1"') + '</tr>';
var template = new Template(s);
Element.insert($('email_chain_container'), {'bottom': template.evaluate(chain)});
$('chain_row_'+chain.index+'_TEMPLATE').value = chain.TEMPLATE_ID;
maxItemsCount++;
},
deleteItem : function(event) {
var tr = Event.findElement(event, 'tr');
if (tr) {
jQuery(tr).remove();
}
}
}
var maxItemsCount = 2;
//]]>
</script>
</td>
</tr>
</tbody>
</table>
</div></form>
</div>
</div>
Hopes this will solve your issue.
For edit you can do it like this :
<tbody id="email_chain_container">
<?php foreach($images as $row){ ?><tr>
<td class="nobr">
your image code
</td></tr>

Upload in MVC4, got 2 parameters in my action but file is empty

I'm trying to upload a file to a directory. The following code worked for me
CONTROLLER
[HttpPost]
public ActionResult Index(HttpPostedFileBase uploadFile)
{
//string path = #"C:\Users\thomas\Desktop";
if (uploadFile != null)
{
string filePath = Path.Combine(Server.MapPath("/files"), Path.GetFileName(uploadFile.FileName));
uploadFile.SaveAs(filePath);
}
return RedirectToAction("Index");
}
HTML PAGE
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<form action="/Post/Index" method="post" enctype="multipart/form-data">
<label for="uploadFile">Upload file: </label>
<input name="uploadFile" id="uploadFile" type="file" />
<input value="uploadFile" type="submit" />
</form>
Now i'm trying to implement this in a function where i create a message which is created by a model that is containing a message and an item class. When i submit the form the model is passed to my savecontroller but the file is null in my parameter controller.
HTML PAGE
Create new message
#model GeoCitytroopers.Models.MessageItemModel
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Event</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Message.MessagePicture)
</div>
<div>
<label for="uploadFile">Upload file: </label>
<input name="uploadFile" id="uploadFile" type="file" />
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Message.MessagePicture)
#Html.ValidationMessageFor(model => model.Message.MessagePicture)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Item.ItemTitle)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Item.ItemTitle)
#Html.ValidationMessageFor(model => model.Item.ItemTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Item.ItemDescription)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Item.ItemDescription)
#Html.ValidationMessageFor(model => model.Item.ItemDescription)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
CONTROLLER
[HttpPost]
public ActionResult Create(HttpPostedFileBase uploadFile, MessageItemModel ViewModel)
{
if (ModelState.IsValid)
{
Utility ut = new Utility();
Item viewItem = ViewModel.Item;
Message viewMessage = ViewModel.Message;
if (uploadFile != null)
{
string filePath = Path.Combine(Server.MapPath("/files"), Path.GetFileName(uploadFile.FileName));
uploadFile.SaveAs(filePath);
}
//ADD USER TO ITEM
viewItem = ut.AddUserToItem(viewItem);
//ADD ITEM
viewItem.ItemCreateddate = DateTime.Now;
//ADD DISTRICT TO ITEM
viewItem.DistrictID = ut.GetUserDistrict();
db.Items.Add(viewItem);
//ADD LINK
viewMessage.Item = viewItem;
db.Messages.Add(viewMessage);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(ViewModel);
}
How can i pass the uploading file to my controller?
Thanks in advance!
You forgot set the correct enctype to the form. You cannot upload files without that:
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" })) {
...
}
Now the upload will work and your uploadFile parameter will not be null.
My initial guess is that the you created using Html helper doesn't have the necessary encrypt on it.
try using
using(#Html.BeginForm("action-name","controller-name",
FormMethod.Post, new { enctype="multipart/form-data"}){
}
with appropriate values for action-name and controller-name

MVC Html.CheckBox list and Jquery Post

my code is
<% using (Html.BeginForm())
{%>
<table>
<tr>
<th>
LabelID_FK
</th>
<th>
LabelName
</th>
<th>
LabelIsDocument
</th>
</tr>
<% foreach (var item in Model)
{ %>
<tr>
<td>
<%: item.LabelID_FK %>
</td>
<td>
<%: item.LabelName %>
</td>
<td>
<%-- <input type="checkbox" value="df" id="chk" onclick="check()" />--%>
<%=Html.CheckBox("chk_"+ item.LabelID_FK)%>
</td>
</tr>
<% } %>
</table>
<p>
<input type="button" value="submit" id="btn" />
</p>
which show checkbox list for document label which user can select it .
i want pass data list which user select checkbox it use jquery post
what i do?
i use this code when user click on button and work very good
[HttpPost]
public ActionResult DocumentLabel(FormCollection model)
{
for (int i = 0; i < model.Count; i++)
{
AriaCRMEntities aria = new AriaCRMEntities();
DocumentLabel label = new DocumentLabel();
string lbl = model[i].ToString();
string[] check = lbl.Split(',');
bool chk = Convert.ToBoolean(check[0]);
string name = model.Keys[i].ToString();
string[] n = name.Split('_');
string lblid = n[1];
if (chk)
{
label.LabelID_FK = Int32.Parse(lblid);
Guid id = Guid.NewGuid();
label.DocumentID_FK = id;
aria.DocumentLabels.AddObject(label);
aria.SaveChanges();
}
}
return Content("0ok");
}
but i want jquery post i need array check box whit select it to pass it to controller?