I have problem with saving value from nouislider.
Here is my code:
html
<form id="campaignForm" th:object="${campaignForm}" method="post" class="form-horizontal">
<input type="hidden" th:field="*{id}" />
<div class="form-group">
<label class="col-sm-3 control-label">Session lifespan (hours): </label>
<div class="col-sm-7">
<div id="basic_slider" th:field="*{sessionLifespan}">
</div>
</div>
<div class="col-sm-2">
<input class="form-control" id="basic_slider_value" th:value="*{sessionLifespan}"/>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<div class="col-sm-9 col-sm-offset-3">
<button class="btn btn-primary" type="submit">Save</button>
<a class="btn btn-white" th:href="#{/campaigns}">Cancel</a>
</div>
</div>
</div>
</div>
</form>
js
var basic_slider = document.getElementById('basic_slider');
noUiSlider.create(basic_slider, {
start: 0,
step: 1,
behaviour: 'tap',
connect: 'upper',
range: {
'min': 0,
'max': 30
}
});
var basicSliderValue = document.getElementById('basic_slider_value');
basic_slider.noUiSlider.on('update', function( values, handle ) {
basicSliderValue.value = values[handle];
});
basicSliderValue.addEventListener('change', function(){
basic_slider.noUiSlider.set(this.value);
});
controller
#GetMapping
public String newCampaign(#RequestParam(value = "appId", required = false) Integer appId, Model model) {
CampaignResource campaign = new CampaignResource();
if (appId != null) {
App app = appService.getApp(appId);
AppResource res = appConverter.convert(app);
campaign.setApp(res);
}
return showPage(campaign, model);
}
protected String showPage(CampaignResource campaign, Model model) {
model.addAttribute("campaignForm", campaign);
model.addAttribute("appList", campaignService.getApps());
model.addAttribute("publisherList", campaignService.getPublishers());
model.addAttribute("sourceList", campaignService.getSources());
return "campaigns/campaign-edit";
}
#PostMapping
public String createCampaign(#ModelAttribute("campaignForm") #Validated CampaignResource resource, BindingResult result, Model model) {
if (result.hasErrors()) {
return showPage(resource, model);
}
return saveCampaign(0, resource);
}
#GetMapping("/{campaignId}")
public String editCampaign(#PathVariable int campaignId, Model model) {
Campaign campaign = campaignService.getCampaign(campaignId);
CampaignResource res = campaignConverter.convert(campaign);
return showPage(res, model);
}
#PostMapping("/{campaignId}")
public String updateCampaign(#PathVariable int campaignId, #ModelAttribute("campaignForm") #Validated CampaignResource resource, BindingResult result, Model model) {
if (result.hasErrors()) {
return showPage(resource, model);
}
return saveCampaign(campaignId, resource);
}
protected String saveCampaign(int campaignId, CampaignResource resource) {
Campaign campaign = populateCampaign(campaignId, resource);
int appId = getAppId(resource);
int publisherId = getPublisherId(resource);
int sourceId = getSourceId(resource);
if (campaignId == 0) {
campaignService.createCampaign(campaign, appId, publisherId, sourceId);
} else {
campaignService.updateCampaign(campaign, appId, publisherId, sourceId);
}
return "redirect:/campaigns";
}
protected Campaign populateCampaign(int campaignId, CampaignResource resource) {
Campaign campaign = null;
if (campaignId == 0) {
campaign = new Campaign();
campaign.setTimeAdded(new Date());
} else {
campaign = campaignService.getCampaign(campaignId);
}
campaign.setCampaignName(resource.getCampaignName());
campaign.setDescription(resource.getDescription());
campaign.setStatus(resource.isStatus() ? UserEnums.StatusCampaign.ACTIVE : UserEnums.StatusCampaign.INACTIVE);
campaign.setSessionLifespan(resource.getSessionLifespan());
return campaign;
}
service
#Transactional
public Campaign createCampaign(Campaign campaign, int appId, int publisherId, int sourceId) {
App app = appRepository.findOne(appId);
campaign.setApp(app);
Publisher publisher = publisherRepository.findOne(publisherId);
campaign.setPublisher(publisher);
Source source = sourceRepository.findOne(sourceId);
campaign.setSource(source);
campaign = campaignRepository.save(campaign);
return campaign;
}
#Transactional
public Campaign updateCampaign(Campaign campaign, int appId, int publisherId, int sourceId) {
campaign.setApp(appRepository.findOne(appId));
campaign.setPublisher(publisherRepository.findOne(publisherId));
campaign.setSource(sourceRepository.findOne(sourceId));
campaign = campaignRepository.save(campaign);
return campaign;
}
converter
#Override
public CampaignResource convert(Campaign campaign) {
CampaignResource resource = new CampaignResource();
resource.setId(campaign.getId());
resource.setCampaignName(campaign.getCampaignName());
resource.setDescription(campaign.getDescription());
resource.setStatus(campaign.getStatus() == StatusCampaign.ACTIVE);
resource.setSessionLifespan(campaign.getSessionLifespan());
if(campaign.getApp() != null) {
resource.setApp(appConverter.convert(campaign.getApp()));
}
if(campaign.getPublisher() != null) {
resource.setPublisher(publisherConverter.convert(campaign.getPublisher()));
}
if(campaign.getSource() != null) {
resource.setSource(sourceConverter.convert(campaign.getSource()));
}
return resource;
}
error
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'campaignForm' on field 'sessionLifespan': rejected value [7.00]; codes [typeMismatch.campaignForm.sessionLifespan,typeMismatch.sessionLifespan,typeMismatch.int,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [campaignForm.sessionLifespan,sessionLifespan]; arguments []; default message [sessionLifespan]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'sessionLifespan'; nested exception is java.lang.NumberFormatException: For input string: "7.00"]
When i move slider it change value in input field, but when i click on save button nothing happend. If i remove th:field="*{sessionLifespan}"from input tag then it save data from form and for sessionLifespan in database it save value 0.
To address the last problem, change your javascript code like this:
var basic_slider = document.getElementById('basic_slider');
var basicSliderValue = document.getElementById('basic_slider_value');
noUiSlider.create(basic_slider, {
start: basicSliderValue.value,
step: 1,
behaviour: 'tap',
connect: 'upper',
range: {
'min': 0,
'max': 30
}
});
basic_slider.noUiSlider.on('update', function( values, handle ) {
basicSliderValue.value = values[handle];
});
basicSliderValue.addEventListener('change', function(){
basic_slider.noUiSlider.set(this.value);
});
The above code will get the value from the field before creating the slider and set the initial value to it. Ofc you still need to use parseInt if you want it to be a int value.
As you may noticed the cause of that problem was pretty simple but still hard to find because you did not notice that there was an error during the validation of the model attribute. In order to prevent similar problems i suggest you to either log any BindingResult related errors or use the th:errors attribute to display them in the form. Both ways will not fix the problem itself, but they will provide the information to fix it. Make sure to check this to learn more about th:error and Form validation in general.
Related
I have an object class Tag {string Key; string Text;} and an object Record that is bind to a storage table.
class Record { [...Id & other properties...]
public string Name { get; set; } // "FirstRecord"
public string Tags { get; set; } // "3,4,9"
}
Updating the Name does not present a problem. But I have some difficulties with the Tags... As you can see the Tags property is the CSV of int keys (say {1:".net",2:"java",3:"perl" ...}).
In the Record's Edit View I build a dictionary with all available Tags:
Dictionary<string, string> tags = ViewData["tags"] as Dictionary<string, string>;
[...]
<div class="form-group">
<label class="col-md-2 control-label">Tags</label>
<div class="col-md-10">
#foreach (var tag in tags)
{
<div class="checkbox-inline">
<label for="tag_#tag.Key">
<input type="checkbox" id="tag_#tag.Key" value="#tag.Key" />
#tag.Value
</label>
</div>
}
</div>
</div>
And finally I have the Edit Post controller, like this
// POST: Records/Edit/5
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, [Bind("Id,Name")] Record record)
{
if (id != record.Id) {
return NotFound();
}
if (ModelState.IsValid) {
try {
await repository.UpdateTableEntityAsync(record);
}
catch (Exception) { [...] }
return RedirectToAction("Index");
}
return View(record);
}
So, I am confused if I should Bind Tags, like [Bind("Id,Name,Tags")], because that value should be taken from all the checked check-boxes values, then concatenated as CSV to be ready to be updated in the storage...
If you want to bind the checkbox values to a string, you could get all the values of checkbox and set the value of model manually. Code below is for your reference.
In view, add a name property for checkbox.
<input type="checkbox" name="tag_#tag.Key" id="tag_#tag.Key" value="#tag.Key" />
In action, we could get all the values of checkbox using Request.Form.
[HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, [Bind("Id,Name")] Record record)
{
if (id != record.Id)
{
return NotFound();
}
record.Tags = "";
foreach (var key in Request.Form.AllKeys)
{
if (key.StartsWith("tag_"))
{
record.Tags += Request.Form[key] + ",";
}
}
if (record.Tags.Length > 0)
{
record.Tags = record.Tags.Remove(record.Tags.Length - 1, 1);
}
if (ModelState.IsValid)
{
try
{
await repository.UpdateTableEntityAsync(record);
}
catch (Exception)
{
}
return RedirectToAction("Index");
}
return View(record);
}
New to web development.
I have a view that allows user to select an excel file.
When submit "preview" button is pressed file is read and data is sent back to the user to preview the data.
Then I want to be able send the model back to the control for db upload.
(this is the part I'm struggling with).
ViewModel:
public class UploadItemsViewModel
{
public List<Item> Items { get; set; }
public int CompanyID { get; set; }
public Company Company { get; set; }
public HttpPostedFileBase upload { get; set; }
public UploadJournalsViewModel()
{
Items = new List<Item>();
}
}
Controller:
public ActionResult Upload(FormCollection formCollection, int CompanyID)
{
if (Request != null)
{
HttpPostedFileBase file = Request.Files["UploadedFile"];
if ((file != null) && (file.ContentLength > 0) && !string.IsNullOrEmpty(file.FileName))
{
string fileName = file.FileName;
string fileContentType = file.ContentType;
byte[] fileBytes = new byte[file.ContentLength];
var data = file.InputStream.Read(fileBytes, 0, Convert.ToInt32(file.ContentLength));
}
}
UploadItemsViewModel itmViewModel = new UploadItemsViewModel { Company = db.Companies.Find(CompanyID), CompanyID = CompanyID };
return View(itmViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(UploadItemsViewModel itmViewModel, string Preview, string Upload)
{
if (ModelState.IsValid)
{
if (itmViewModel.upload != null && itmViewModel.upload.ContentLength >0)
{
try
{
itmlViewModel.Items = App.Services.ItemsMassUploadFileRead.ReadExcelFile(itmViewModel.upload, db.Companies.Find(itmViewModel.CompanyID));
if (string.IsNullOrEmpty(Preview))
{
foreach (var itm in itmViewModel.Items)
{
itm.StartDate = DateTime.Today;
itm.CompanyID = itmViewModel.CompanyID;
itm.User = null;
itm.Items.Add(itm);
db.SaveChanges();
}
return View();
}
else
{
return View(itmViewModel);
}
} }
catch (Exception ex)
{
ModelState.AddModelError("File", ex.Message.ToString());
return View(itmViewModel);
}
}
else
{
ModelState.AddModelError("File", "Please Upload Your file");
}
}
return View(itmViewModel);
}
View:
#using (Html.BeginForm("Upload", "ItemsUpload", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.CompanyID)
<div class="form-group">
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default">
Browse… <input type="file" style="display: none;" accept=".xlsx" name="upload">
</span>
</label>
<input type="text" class="form-control " readonly>
</div>
<span class="help-block">
Please use a provided Excel template
</span>
</div>
<div class="form-group">
<input type="submit" value="Preview" name ="Preview" class="btn btn-default" disabled style="display: none" id="submit"/>
</div>
<div class="form-group">
<input type="submit" value="Upload" name="Upload" class="btn btn-default" id="Upload" />
</div>
<div class="help-block" id="previewHelp" style="display: none">
Preview results and scroll down to upload data to the database.
</div>
if (Model.Journals.Count != 0)
{
table here to preview the upload
}
After clicking the Upload button model comes back without the "items" collection.
The Items list will be always null in the controller, because you don't rendered any input on the View with the name Items
Hey guys I have the following issue with Asp SignalR. I want to have a chat with Admins and Users. I have 1 View with two divs (! for the Admin and 1 for the users), which I show or hide by checking the user. So far so good, everything works ! Both the admins and users get the necessary divs and can exchange messages - red div admin, blue div user.. Take a look at the code and I'll explain where I get a problem.
<div class="Admin" id="divMessageAdmin" style="background-color:red;">
<div class="welcome"></div><br />
<div id="divWaitingUser"></div><br />
<input id="txtMessage" type="text" />
<input id="btnSendMessage" type="button" value="Send" />
<div id="divAdminMessage"></div>
</div>
<div class="User" id="divMessageUser" style="background-color:blue;">
<div class="welcome"></div><br />
<input id="txtUserMessage" type="text" />
<input id="btnSendUserMessage" type="button" value="Send" />
<div id="divUserMessage"></div>
</div>
<input id="hUserId" type="hidden" />
<input id="hId" type="hidden" />
<input id="hUserName" type="hidden" />
<input id="hGroup" type="hidden" />
#section scripts {
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.signalR-2.2.1.min.js"></script>
<script src="~/signalr/hubs" type="text/javascript"></script>
<script>
$(function () {
var objHub = $.connection.chatHub;
loadClientMethods(objHub);
$.connection.hub.start().done(function () {
loadEvents(objHub);
});
});
function loadEvents(objHub) {
var name = '#HttpContext.Current.User.Identity.Name';
objHub.server.connect(name);
//alert(name);
$('#btnSendMessage').click(function () {
var msg = $("#txtMessage").val();
if (msg.length > 0) {
var username = $('#hUserName').val();
document.getElementById('txtMessage').value = "";
// <<<<<-- ***** Return to Server [ SendMessageToGroup ] *****
objHub.server.sendMessageToGroup(username, msg);
}
});
$('#btnSendUserMessage').click(function () {
// alert("wrks");
var msg = $("#txtUserMessage").val();
if (msg.length > 0) {
var username = $('#hUserName').val();
document.getElementById('txtUserMessage').value = "";
// <<<<<-- ***** Return to Server [ SendMessageToGroup ] *****
objHub.server.sendMessageToGroup(username, msg);
}
});
$("#txtMessage").keypress(function (e) {
if (e.which == 13) {
$('#btnSendMessage').click();
}
});
}
function loadClientMethods(objHub) {
objHub.client.getMessagesAdmin = function (userName, message) {
$(".txtMessage").val('');
$('#divAdminMessage').append('<div><p>' + userName + ': ' + message + '</p></div>');
var height = $('#divAdminMessage')[0].scrollHeight;
$('#divAdminMessage').scrollTop(height);
}
objHub.client.getMessagesUser = function (userName, message) {
$("#txtMessage").val('');
$('#divUserMessage').append('<div><p>' + userName + ': ' + message + '</p></div>');
var height = $('#divUserMessage')[0].scrollHeight;
$('#divUserMessage').scrollTop(height);
}
objHub.client.onConnected = function (id, userName, UserID, userGroup, flag) {
alert(flag);
var strWelcome = 'Welcome' + +userName;
$('.welcome').append('<div><p>Welcome:' + userName + '</p></div>');
$('#hId').val(id);
$('#hUserId').val(UserID);
$('#hUserName').val(userName);
$('#hGroup').val(userGroup);
if ( flag == "1") {
$("#divMessageUser").hide();
$("#divMessageAdmin").show();
}
else {
$("#divMessageUser").show();
$("#divMessageAdmin").hide();
}
}
}
</script>
}
The thing is, that I want these two divs to be in separated Partial Views. This is what I'm trying. At the beginning of my page I check if the user is authenticated, if it is I fire a [ChildActionOnly] action method in my ChatController:
<h2>Chat</h2>
#{
if (!User.Identity.IsAuthenticated)
{
#Html.Partial("_UnauthenticatedUserForm");
}
else
{
Html.RenderAction("AuthenticatedUsersChat");
}
}
and my action method in the controller
[ChildActionOnly]
public ActionResult AuthenticatedUsersChat()
{
AppContext db = new AppContext();
User user = db.Users.Single(usr => usr.Email == User.Identity.Name);
int isAdmin = user.AdminCode;
if (isAdmin == 0)
{
return PartialView("_UserChatPartial");
}
else
{
return PartialView("_AdminChatPartial");
}
}
this works and the partial views are returning in the way I want. In both partial views I've moved the divs ONLY! Admin Partial:
<div class="Admin" id="divMessageAdmin" style="background-color:red;">
<div class="welcome"></div><br />
<div id="divWaitingUser"></div><br />
<input id="txtMessage" type="text" />
<input id="btnSendMessage" type="button" value="Send" />
<div id="divAdminMessage"></div>
</div>
and UserPartial
<div class="User" id="divMessageUser" style="background-color:blue;">
<div class="welcome"></div><br />
<input id="txtUserMessage" type="text" />
<input id="btnSendUserMessage" type="button" value="Send" />
<div id="divUserMessage"></div>
</div>
BUT somehow then only the Administrator can see the messages. The user can send messages (admin receives it), but the user cannot see his or admins messages - result. I simply don't see any logic why only the user can't see the messages. Please if you have any ideas help me. Thanks in advance !
my method for the messages in the hub class
public void SendMessageToGroup(string userName, string message)
{
if (UsersList.Count != 0)
{
var strg = (from s in UsersList where (s.Email == userName) select s).First();
MessageList.Add(new MessageInfo { UserName = userName, Message = message, UserGroup = strg.UserGroup });
string strgroup = strg.UserGroup;
Clients.Group(strgroup).getMessagesAdmin(userName, message);
Clients.Group(strgroup).getMessagesUser(userName, message);
}
}
// End SendMessage
and the connection method in the hub
public void Connect(string userName)
{
//if freeflag==0 ==> Busy
//if freeflag==1 ==> Free
//if tpflag==0 ==> User
//if tpflag==1 ==> Admin
var id = Context.ConnectionId;
string userGroup = "";
AppContext db = new AppContext();
var userInfo = (from m in db.Users
where m.Email == HttpContext.Current.User.Identity.Name
select new { m.UserId, m.Email, m.AdminCode, m.FirstName, m.LastName }).FirstOrDefault();
try
{
if ((int)userInfo.AdminCode == 0)
{
var strg = (from s in UsersList where (s.tpflag == "1") && (s.freeflag == "1") select s).First();
userGroup = strg.UserGroup;
strg.freeflag = "0";
//now add USER to UsersList
UsersList.Add(new User { ConnectionId = id, UserId = userInfo.UserId, Email = userName, UserGroup = userGroup, freeflag = "0", tpflag = "0", });
var flag = (from s in UsersList where (s.Email == userName) select s.tpflag);
Groups.Add(Context.ConnectionId, userGroup);
Clients.Caller.onConnected(id, userName, userInfo.UserId, userGroup, flag);
}
else
{
UsersList.Add(new User { ConnectionId = id, UserId = userInfo.UserId, Email = userName, UserGroup = userInfo.AdminCode.ToString(), freeflag = "1", tpflag = "1" });
var flag = (from s in UsersList where (s.Email == userName) select s.tpflag);
Groups.Add(Context.ConnectionId, userInfo.AdminCode.ToString());
Clients.Caller.onConnected(id, userName, userInfo.UserId, userInfo.AdminCode.ToString(), flag);
}
}
catch
{
Clients.Caller.NoExistAdmin();
}
}
Sounds like your "blue" user is not in the group strgroup which you're trying to send to. Set a breakpoint to this line in the SendMessageToGroup method and check it.
Also strange code in if ((int)userInfo.AdminCode == 0) why to get First from UsersList and then add to it again? May be exception here?
This is my first post to StackOverflow. I hope this is useful.
I have a Razor view that is intended to allow editing of the displayable properties of a model containing either pre-defined values or null values. The view should not change the contents of the model's properties unless the user changes them intentionally by editing them on in the UI based on the view. The view behaves correctly, except with regard to a property of type byte[] that contains image data: Model.ImageData
#using (Html.BeginForm("Edit", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" } ))
{
#Html.EditorForModel()
<div class="editor-label">Image</div>
<div class="editor-field">
#if (Model.ImageData == null)
{
#: No image has been assigned in the database.
}
else
{
<img width="150" height="150" src="#Url.Action("GetImage", "Product", new { Model.ID} )" />
}
<div>Upload new image: <input type="file" name="Image" /></div>
</div>
<input type="submit" value="Save" />
}
The above view works as intended for all properties in the model except Model.ImageData. In this case, posting causes any previously set Model.ImageData to be set to null. I have confirmed that the Model.ImageData is set to null during post by verifying that prior to posting, Model.ImageData contains a valid byte array (with the expected image).
The controller code for the above view is:
public ViewResult Edit(int id)
{
Product product = repository.Products.FirstOrDefault(p => p.ID == id);
// breakpoint here shows that all model properties including product.ImageData are populated and valid.
return View(product);
}
[HttpPost]
public ActionResult Edit(Product product, HttpPostedFileBase Image)
{
if (ModelState.IsValid)
{
// breakpoint here shows that product.ImageData is null (but all other model properties are still populated with data).
if (Image != null)
{
product.ImageMimeType = Image.ContentType;
product.ImageData = new byte[Image.ContentLength];
Image.InputStream.Read(product.ImageData, 0, Image.ContentLength);
}
repository.SaveProduct(product);
TempData["Message"] = string.Format("{0} has been saved", product.Name);
return RedirectToAction("Index");
}
else
{
return View(product);
}
}
And here is the respository code that updates the model (though the model is changing before this code is called):
public void SaveProduct(Product product)
{
if (product.ID == 0)
{
context.Products.Add(product); // why doesn't this try to save ID = 0 to the ID field of the product in the database??
}
else
{
Product dbEntry = context.Products.Find(product.ID);
if (dbEntry != null)
{
dbEntry.Name = product.Name;
dbEntry.Description = product.Description;
dbEntry.Category = product.Category;
dbEntry.Price = product.Price;
dbEntry.ImageData = product.ImageData;
dbEntry.ImageMimeType = product.ImageMimeType;
}
}
context.SaveChanges();
}
What am I doing wrong?
This is really where you should consider using a ViewModel class instead. But to keep your current ways of doing things with minimal changes, try modifying the SaveProduct() method to the following:
public void SaveProduct(Product product, bool updateImage = false)
{
context.Products.Attach(product);
// mark product as modified
var entry = context.Entry(product);
entry.State = EntityState.Modified;
entry.Property(e => e.ImageData).IsModified = updateImage;
entry.Property(e => e.ImageMimeType).IsModified = updateImage;
context.SaveChanges();
}
and modify the controller code to:
...
var updateImage = false;
if (Image != null)
{
updateImage = true;
product.ImageMimeType = Image.ContentType;
product.ImageData = new byte[Image.ContentLength];
Image.InputStream.Read(product.ImageData, 0, Image.ContentLength);
}
repository.SaveProduct(product, updateImage);
....
I am new to asp .net mvc 4.0. i have given model. i am not getting how can i create view for model. I am facing problem at IList JournalEntries. other entry i am able to do.
public class Journal : BaseClass
{
public virtual string VoucherNo { get; set; }
public virtual DateTime VoucherDate { get; set; }
public string VoucherDateView {
get
{
return VoucherDate.ToShortDateString();
}
}
public IList<JournalEntry> JournalEntries { get; set; }
public IList<Ledger> Accounts { get; set; }
public double TotalAmount
{
get
{
double sum = 0;
if (JournalEntries != null && JournalEntries.Count>0)
foreach (var journal in JournalEntries)
sum = journal.Principal + journal.Interest+sum;
return sum;
}
}
}
I have tried below view but add entry doesn't works.
#model Sms.CoreSociety.Journal
#{
ViewBag.Title = "Create";
}
#{
string data = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model);
}
<script type="text/javascript">
$(document).ready(function () {
$('#document').validate();
$("#VoucherDate").mask("99/99/9999", { placeholder: " " });
function entryVm(entries) {
var self = this;
self.entryList = ko.observableArray(entries);
self.entry = ko.observable();
self.rowClick = function(entry1) {
alert("Delete alert");
self.dispatchList.remove(entry1);
};
self.addEntry = function() {
alert("Add alert");
this.entryList.push({ AccountName_AccountHead: "", DebitCredit: "", Principal: "0.0", Interest: "0.0", Narration: ""});
};
}
var models = #Html.Raw(Json.Encode(Model.JournalEntries)) ;
ko.applyBindings(new entryVm(models));
});
</script>
#using (Html.BeginForm(null, null, FormMethod.Post, new Dictionary<string, object>() { { "class", "form-horizontal" }, { "id", "document" } }))
{
#Html.ValidationSummary(true)
<fieldset>
<div class="row">
<div class="span1">
<label>Voucher No</label>
</div>
<div class="span5">
#Html.DisplayFor(model => model.VoucherNo)
</div>
</div>
<div class="row">
<div class="span1">
<label>Voucher Date</label>
</div>
<div class="span5">
#Html.TextBoxFor(model => model.VoucherDate, "{0:dd/MM/yyyy}", new Dictionary<string, object>() { { "class", "required" } })
</div>
</div>
<div class="row">
<div class="span1">
<label>Amount</label>
</div>
<div class="span5">
#Html.DisplayFor(model => model.TotalAmount)
</div>
</div>
<input type="submit" value="Save" class="btn" id="submit"/>
#if (Model.Id != new Guid())
{
<div style="float: right">
<a class="btn btn-danger" href='#Url.Action("Delete")/#Model.Id' aria-hidden="true">Delete</a>
</div>
}
</fieldset>
}
<h4>Journal Entry</h4>
<p >Entry for<span data-bind="text: entryList().length"> </span> entry(s)</p>
<button data-bind="click: addEntry" class="btn">Add Record</button>
<table>
<tbody data-bind="template: { name: 'entryRowTemplate', foreach: entryList }"></tbody>
</table>
<script type="text/html" id="entryRowTemplate">
<tr>
<td>AccountName_AccountHead: \$ <input data-bind="value: AccountName.AccountHead"/> </td>
<td>DebitCredit: \$ <input data-bind="value: DebitCredit"/></td>
<td>Principal: \$ <input data-bind="value: Principal"/></td>
<td>Interest: \$ <input data-bind="value: Interest"/></td>
<td>Narration: \$ <input data-bind="value: Narration"/></td>
<td>Delete</td>
</tr>
</script>
below is my Journal controller
using System;
using System.Linq;
using System.Web.Mvc;
using Sms.CoreSociety;
using System.Collections.Generic;
namespace SmsModernUI.Controllers
{
public class JournalController : BaseController
{
//
// GET: /AccountGroup/
public ActionResult Index()
{
var journals = Repository.GetAll<Journal>().OrderBy(x => x.VoucherNo);
return View(journals);
}
public ActionResult Create(Guid id)
{
if (id == new Guid())
{
var journal = new Journal();
string lastvoucherno = Repository.GetAll<Journal>().OrderBy(x => x.VoucherNo).Last().VoucherNo;
journal.VoucherNo = (int.Parse(lastvoucherno) + 1).ToString();
journal.VoucherDate = System.DateTime.Now;
journal.JournalEntries = new List<JournalEntry>();
journal.Accounts = Repository.GetAll<Ledger>();
return PartialView(journal);
}
var journal1 = Repository.Get<Journal>(id);
journal1.JournalEntries = Repository.GetAll<JournalEntry>(x => x.Journal.Id == id);
journal1.Accounts = Repository.GetAll<Ledger>();
return PartialView(journal1);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult Create(Journal journal)
{
if (journal.Id == new Guid())
{
var jj = Repository.Save(journal);
foreach (var journalentry in journal.JournalEntries)
{
journalentry.Id = jj.Id;
Repository.Save(journalentry);
}
}
else
{
Journal jr = Repository.Get<Journal>(journal.Id);
var entries = Repository.GetAll<JournalEntry>(x=>x.Journal.Id == journal.Id);
foreach (var entry in entries)
{
Repository.Delete(entry);
}
var jj = Repository.Save(journal);
foreach (var journalentry in journal.JournalEntries)
{
journalentry.Id = jj.Id;
Repository.Save(journalentry);
}
}
return RedirectToAction("Index");
}
public ActionResult Index1()
{
Journal journal1 = Repository.Get<Journal>(new Guid("7A6EEBBC-2F3A-4A27-ACF8-A1D40115A68F"));
journal1.JournalEntries = Repository.GetAll<JournalEntry>(x => x.Journal.Id == journal1.Id);
journal1.Accounts = Repository.GetAll<Ledger>();
return View(journal1);
}
public ActionResult Delete(Guid id)
{
Journal jr = Repository.Get<Journal>(id);
var entries = Repository.GetAll<JournalEntry>(x => x.Journal.Id == jr.Id);
foreach (var entry in entries)
{
Repository.Delete(entry);
}
var result = Repository.Delete(jr);
return RedirectToAction("Index");
}
[HttpPost]
public ActionResult Create1(Journal journal)
{
var temp = journal;
return RedirectToAction("Create",journal.Id);
}
}
}
Views are not genereted from models. You need Controller Action method to pass your model to View.
public ActionResult()
{
var model = new Journal
{
//**define here value of model's properties, that you need in View
}
return View(model);
}
EDITED: After your addition.
I would devide it into two parts. Create ViewModel and pass it from View To Controller.
public JurnalViewModel
{
public Journal journal {get; set;}
public IList<JournalEntry> JournalEntries {get; set;}
}
Than in Create action first create journal and after foreach JournalEntries in model create new JournalEntry.
EDITED 2 To your comment. Quick sample:
[HttpPost]
public ActionResult Create (JurnalViewModel model)
{
var journal = new Journal();
db.Journals.Add(journal);
journal.name = model.journal.name
.....
//**some code
db.SaveChanges()
foreach(var item in model.JournalEntries )
{
var entry = new JournalEntry()
db.JournalEntries .Add(entry);
entry.property = item.property;
....
//**some code
db.SaveChanges()
}
}
Your problem is that you have no class constructor for JournalEntries.
public Journal()
{
JournalEntries = new List<JournalEntry>();
Accounts = new List<Ledger>();
}
Right click to your Action method inside controller and click add view then check create strongly typed-view checkbox then choose your desired model from dropdown in displayed dialogue box