SignalR and MVC 5 partial views - asp.net-mvc

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?

Related

Validation of the form submitted by Ajaxform jQuery plugin in ASP.NET MVC 5

public class File
{
[Key]
public int FileID { get; set; }
[Display(Name = "atachfile")]
[MaxLength(150)]
public string atachFile{ get; set; }
}
I wrote the controller codes of the editing section like this...
// GET: /Users/FileUpload/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
File file = db.Files.Find(id);
if (file == null)
{
return HttpNotFound();
}
return View(file);
}
// POST: /Users/FileUpload/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "FileID,atachFile")] File file, HttpPostedFileBase LearnAtach , int id)
{
if (ModelState.IsValid)
{
if (LearnAtach != null)
{
if (file.atachFile != null)
{
System.IO.File.Delete(Server.MapPath("/File/LearnAtach/" + file.atachFile));
}
string[] FileExtension = { ".zip" };
string FileType = Path.GetExtension(LearnAtach.FileName);
double FileSize = (LearnAtach.ContentLength / 1024.0) / 1024;
if (FileExtension.Contains(FileType.ToLower()))
{
if (FileSize > 950)
{/
ViewBag.sizeatach = "error..filexize>950";
return View(file);
}
file.atachFile = Guid.NewGuid() + Path.GetExtension(LearnAtach.FileName);
LearnAtach.SaveAs(Server.MapPath("/File/LearnAtach/" + file.atachFile));
}
else
{
ViewBag.typeatach = "filyType != zip";
this.TempData["UnSuccessMessage"] = "filyType != zip";
return View(file);
}
}
fileRepository.UpdateFile(file);
fileRepository.save();
return RedirectToAction("Index");
}
return View(file);
}
View markup:
#model DataLayer.File
#using (Html.BeginForm("Edit", "FileUpload", FormMethod.Post, new { enctype = "multipart/form-data", id = "fileform" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.FileID)
<div class="form-group">
#Html.LabelFor(model => model.atachFile, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.atachFile, new { type = "file", Name = "LearnAtach" })
#Html.ValidationMessageFor(model => model.atachFile)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="submit" class="btn btn-success" />
</div>
</div>
</div>
}
<div class="progress progress-striped" style="direction: ltr">
<div class="progress-bar progress-bar-success">0%</div>
</div>
<br /><br />
#section scripts
{
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/modal.js"></script>
<script>
$(document).ready(function() {
var bar = $('.progress-bar');
var percent = $('.progress-bar');
var status = $('#status');
$("#fileform").ajaxForm({
beforeSend: function() {
status.empty();
var percentVal = '0%';
bar.width(percentVal);
percent.html(percentVal);
},
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
bar.width(percentVal);
percent.html(percentVal);
//show preloder
},
success: function() {
var percentVal = '100%';
bar.width(percentVal);
percent.html(percentVal);
//hide preloder
$("#Success").modal();
},
complete: function(xhr) {
status.html(xhr.responseText);
}
});
});
</script>
}
Now the file is uploaded but the validators are not applied .. How can I show the filesize limit and filetype the file on the client side to the user and apply
In fact, if the condition of file size and format is also wrong, the uploaded file will be saved in the (/File/LearnAtach)folder, but because the condition is incorrect, its path will not be stored in the database.
Also, if the condition is true, the condition whether this file already exists or deletes the previous one will not be checked. Thanks

Display a list in a partial view at post

I have this code in my controller:
[HttpPost]
public ActionResult Index(double userLat, double userLng)
{
var context = new weddingspreeEntities();
var coordinates = context.Venues
.Select(loc => new { vname = loc.VenueName, lat = loc.VenueLat, lng = loc.VenueLong })
.ToList();
string venueName = string.Empty;
List<SearchModel.DistLocation> venDistList = new List<SearchModel.DistLocation>();
for (int i = 0; i < coordinates.Count; i++)
{
string name = coordinates[i].vname;
double? lat = coordinates[i].lat;
double? lng = coordinates[i].lng;
var loc1Lat = lat.Value;
var loc1Lng = lng.Value;
var loc2Lat = userLat;
var loc2Lng = userLng;
double distance = TrackingHelper.CalculateDistance(
new SearchModel.Location() { Latitude = loc1Lat, Longitude = loc1Lng },
new SearchModel.Location() { Latitude = loc2Lat, Longitude = loc2Lng });
//convert kilometers to miles
double distMiles = distance * 0.621371192;
venueName = name;
venDistList.Add(new SearchModel.DistLocation() { venName = name, Distance = distMiles });
}
return View(venDistList);
}
I have this code in my view:
<div class="row">
<div class="form-group">
<div class="col-md-6">
#using (Html.BeginForm("Search", "Home", FormMethod.Post))
{
#*#Html.TextBoxFor(model => model.cityName)*#
<label>Enter City and State or Zip Code</label>
<input type="text" id="citystate" name="citystate" />
<label>Enter Your Wedding Date</label>
<input class="datefield" data-val="true" data-val-required="Date is required" id="weddingDate" name="weddingDate" type="date" value="1/11/1989" />
<label>Enter Your Guest Count</label>
<input type="text" id="guestcount" name="guestcount" />
<input type="button" id="search" name="search" value="Search for Venues" />
}
</div>
<!--This is the div where the google map will render -->
<div class="col-md-6">
<div id="map_canvas" style="height: 600px;"></div>
</div>
</div>
</div>
<div>
#Html.Partial("_SearchResults")
</div>
I have omitted some of my view for brevity
This is the partial view I am trying to render:
#model IEnumerable<WeddingSpree_Alpha.Models.SearchModel.DistLocation>
#{
Layout = null;
}
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
foreach (var item in Model)
{
#item.venName
#item.Distance
}
}
What I am trying to do is to have the user enter the values in the search box and then after the click post the results (in the list named venDistList) to the view using a foreach statement.
The model looks like this:
public class SearchModel
{
public string cityName { get; set; }
public DateTime weddingDate { get; set; }
public int guestCount { get; set; }
public class Location
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public class DistLocation
{
public string venName { get; set; }
public double Distance { get; set; }
}
}
I would like the list results to populate after the button click (post) on the page. I thought my code would do that however. I get the following error:
System.NullReferenceException: 'Object reference not set to an instance of an object'
I know that error happens when you try to use a model that is not populated yet but I thought I did that in my controller code? What exactly could be throwing that error?
This is the controller code for my partial view:
public ActionResult _SearchResults(SearchModel model)
{
return View();
}
If you are not at least instantiating an instance of IEnumerable to pass back (even if it is empty) then it will throw the null reference when you try to iterate throught the model in the partial view.
Edit: (Code trimmed down for example) Your original error is that you are trying to iterate through an object that does not exist. The below will show you how to make user of an Ajax call on your form submit to dynamically generate your partial view and attach it to your main page
Controller:
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult _SearchResults(string citystate, DateTime? weddingDate, double? guestcount)
{
List<SearchModel.DistLocation> venDistList = new List<SearchModel.DistLocation>();
venDistList.Add(new SearchModel.DistLocation() { venName = "weee1", Distance = 2 });
venDistList.Add(new SearchModel.DistLocation() { venName = "weee2", Distance = 4 });
venDistList.Add(new SearchModel.DistLocation() { venName = "weee3", Distance = 6 });
return PartialView(venDistList);
}
Index.cshtml:
#{
ViewBag.Title = "Home Page";
}
#*This is our form which will feed our user input and drive our search results output*#
<div class="row">
<div class="form-group">
<div class="col-md-6">
<form id="searchMe">
<label>Enter City and State or Zip Code</label>
<input type="text" id="citystate" name="citystate" />
<label>Enter Your Wedding Date</label>
<input class="datefield" data-val="true" data-val-required="Date is required" id="weddingDate" name="weddingDate" type="date" value="1/11/1989" />
<label>Enter Your Guest Count</label>
<input type="text" id="guestcount" name="guestcount" />
<button type="submit" class="btn btn-primary">Search for Venues</button>
</form>
</div>
</div>
</div>
<div class="row">
#*This is where we want our search results to appear when user hits submit on our form*#
<div id="SearchResult"></div>
</div>
#section scripts {
<script>
$(document).ready(function () {
//When the user hit the submit button we will post the form results to our partial view controller
$('#searchMe').submit(function () {
$.ajax({
method: "POST",
url: "/Home/_SearchResults",
data: $(this).serialize(),
success: function (result) {
//When then load our partial view into our containing div on the main page
$('#SearchResult').html(result);
}
});
return false;
});
});
</script>
}
Partial View (_SearchResult.cshtml)
#model IEnumerable<deletemeweb2.Models.SearchModel.DistLocation>
#{
Layout = null;
}
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Search Results</h3>
</div>
<div class="panel-body">
#if (Model != null || Model.Count() < 1)
{
using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
foreach (var item in Model)
{
<p>#item.venName</p>
<p>#item.Distance</p>
}
}
}
else
{
<p>No results found</p>
}
</div>
</div>

Thymeleaf doesn't take value from input

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.

Struts 2 Action Message - not displayed on the UI

I want to display an info message to the user on submit of the action but the message is not getting displayed. It works if I use addActionError but I want to display as an info message and hence using the addActionMessage. Please let me know where I went wrong.
public void validateUser() {
List<Product> existingProductList = new ArrayList<Product>();
try {
IProductRepository productRepository = daoRepository
.getProductRepository();
existingProductList = digestRepository
.searchDigests(null, null);
} catch (Exception e) {
e.printStackTrace();
}
for (Product product: existingProductList ) {
if (prod.getQuartzNumber().equalsIgnoreCase(
product.getQuartzNumber())) {
addActionMessage("The Quartz number entered already exists");
break;
}
}
}
Below is my jsp code:
<div id="content-wrapper">
<div id="product_create_header">
<h2>Create a New product</h2>
</div>
<!-- Error messages -->
<dl id="dyna_product_create_errors" class="error"></dl>
<form id="product_create_form" method="post">
<!-- product identifiers -->
<!-- product details -->
<fieldset id="product_create_details">
<legend>product Details</legend>
<div class="form-element">
<label for="product_create_name">Name:</label><br />
<input id="product_create_name" type="text" name="product.name" value="" maxlength="256" /><br />
<span id="product_create_name_error" class="error"></span>
</div>
<div class="form-element">
<label for="product_create_presentation_order">Quartz Order:</label><br />
<input id="product_create_presentation_order" type="text" name="product.quartzOrder" value="" maxlength="256" /><br />
<span id="product_create_presentation_order_error" class="error"></span>
</div>
</fieldset>
<!-- Form buttons -->
<div id="product_create_buttons" class="formButtons">
<button id="product_create_button_cancel" type="button" title="Reset" onclick="resetproductCreateForm();">Reset</button>
<button id="product_create_button_submit" type="button" title="Submit" onclick="createproduct();">Submit</button>
</div>
</form>
</div>
I see that they have added
for displaying the error, not sure how to display for messages
Below is my js code:
function createproduct() {
dojo.xhrPost( {
url :"services/product/create",
handleAs :"json",
preventCache :"true",
load : function(returnObject, ioArgs) {
if (returnObject.status == "success") {
product = returnObject.body;
displayproductDetail();
}
else if (returnObject.status == "input") {
var errorList = dojo.byId("dyna_product_create_errors");
handleActionErrors(returnObject.actionErrors, errorList);
handleActionMessage(returnObject.actionMessages, messageList);
handleCreateproductsFieldErrors(returnObject.fieldErrors);
}
else if (returnObject.status == "error") {
resetproductSearchFormErrors();
var errorList = dojo.byId("dyna_product_create_errors");
handleActionErrors(returnObject.actionErrors, errorList);
}
},
error : function(error) {
handleHTTPError(error);
},
form :'product_create_form'
});
}
private String myActionMessage;//Getter and setter Method
public void validateUser() {
List<Product> existingProductList = new ArrayList<Product>();
try {
IProductRepository productRepository = daoRepository
.getProductRepository();
existingProductList = digestRepository
.searchDigests(null, null);
} catch (Exception e) {
e.printStackTrace();
}
for (Product product: existingProductList ) {
if (prod.getQuartzNumber().equalsIgnoreCase(
product.getQuartzNumber())) {
addActionMessage("The Quartz number entered already exists");
getMyActionMessage("The Quartz number entered already exists");
break;
}
}
}
And your result.jsp file
<s:actionmessage/>
<s:property value="myActionMessage"/>

Return the search result after HTTPPOST in MVC

I have search form to search by : site, user, status and date. After searched I will do Reject, Re-submit or Approve to call the controller action for update the status in the database. My code are as below:
/// View :
#Html.ValidationMessage("CustomError")
#Html.ValidationSummary(true)
#using (Html.BeginForm()) // Begin Form
{
<table>
<tr>
<td>Site:</td>
<td>#Html.DropDownList("sites", (IEnumerable<SelectListItem>)ViewBag.sites, "-- ALL --", new { style = "width: 300px;" })</td>
<td>Status:</td>
<td>#Html.DropDownList("status", (IEnumerable<SelectListItem>)ViewBag.status, "-- ALL --", new { style = "width: 150px;" })</td>
<td>PO No:</td>
<td>#Html.TextBox("PONumber", null, new { style = "width:150px" })</td>
</tr>
<tr>
<td>User: </td>
<td>#Html.DropDownList("user", (IEnumerable<SelectListItem>)ViewBag.user, "-- ALL --", new { style = "width: 300px;" })</td>
<td>Department:</td>
<td>
#Html.DropDownList("department", (IEnumerable<SelectListItem>)ViewBag.department, "-- ALL --", new { style = "width: 150px;" })
</td>
<td>Transaction Date:
</td>
<td>
#*<input type="text" id="TransactionDate" name="TransactionDate" style="width:210px" />*#
#*#Html.TextBox("TransactionDate", null, new { #class="datefield", style = "width:150px", #Value = DateTime.Now.ToShortDateString() })*#
#Html.TextBox("TransactionDate", null, new { #class="datefield", style = "width:150px" })
</td>
</tr>
</table>
<input type="submit" value="Search" />
// Here is the search result table
<input type="submit" value="Re-Submit" name="action" />
<input type="submit" value="Approve" name="action" />
<input type="submit" value="Reject" name="action" />
} // End Form
//// Controller
// HTTP Get
public ActionResult POHeader(string sites, string user, string department,
string status, string PONumber, string TransactionDate, bool IsRedirectAction = false)
{
// Populate Dropdown List
GetSiteDropdownList(SiteId);
GetUserDropdownList(UserId);
GetDepartmentDropdownList(DepartmentId);
GetStatusDropdownList(StatusId);
var PO = from p in db.X_PO_HDR
select p;
// Get Selected Site
if ((!string.IsNullOrEmpty(sites)) || ((TempData["selectedsite"] != null)))
{
if (sites.Length > 0)
{
if (IsRedirectAction)
{
SiteId = (string)TempData["selectedsite"];
//sites = SiteId;
}
else
{
SiteId = sites;
TempData["selectedsite"] = SiteId;
}
// Get Selected Site
PO = PO.Where(p => p.Site_Id == SiteId);
}
}
if (!string.IsNullOrEmpty(user) || ((TempData["selectedUser"] != null)))
{
if (user.Length > 0)
{
if (IsRedirectAction)
{
UserId = (string)TempData["selectedUser"];
}
else
{
UserId = user;
TempData["selectedUser"] = UserId;
}
// Filter by User
PO = PO.Where(p => p.Created_By == UserId);
}
}
// Get Selected Department
if (!string.IsNullOrEmpty(department) || ((TempData["selectedDepartment"] != null)))
{
if (department.Length > 0)
{
if (IsRedirectAction)
{
DepartmentId = (string)TempData["selectedDepartment"];
}
else
{
DepartmentId = department;
TempData["selectedDepartment"] = DepartmentId;
}
// Filter by Department
PO = PO.Where(p => p.Purch_Dept == DepartmentId);
}
}
PO = PO.OrderBy(o => o.Txn_DT);
// check if TempData contains some error message and if yes add to the model state.
if (TempData["CustomError"] != null)
{
ModelState.AddModelError(string.Empty, TempData["CustomError"].ToString());
}
return View(PO.ToList());
}
/// HttpPost Action
[HttpPost, ActionName("POHeader")]
[MultiButton(MatchFormKey = "action", MatchFormValue = "Reject")]
public ActionResult Reject(int[] selectedList)
{
string var1 = collection["sites"];
UpdateListStatus(selectedList, "X", "Rejected");
TempData["CustomError"] = selectedList.Count().ToString() + " record(s) has been successfully " + ActionString + "!";
return RedirectToAction("POHeader", new { IsRedirectAction = true });
}
Question: How to get back the search values?
1. Do I need to pass all the parameters again at HTTPPost Action? (any better way to solve?)
2. CustomError message is not working. (Message appear after next search is done)
Thanks,
Si Thu
I would start out by binding the View to a model. By doing this you can pass the entire model back to your method, then if there are issues with the form and you need to show it again with the values, you just return back the view along with the model you sent.
[HttpPost]
public ActionResult POHeader(FormModel model)
{
if (ModelState.IsValid)
{
// Do whatever you want to do and redirect to wherever you want to go from here.
}
// If the Model is invalid then simply return back the view along with the invalid model.
return View(model)
}
See the following article for more information on Model Binding
http://www.codeproject.com/Articles/159749/ASP-NET-MVC-Model-Binding-Part1
Here is another article on Client Side Model validation
http://www.codeproject.com/Articles/718004/ASP-NET-MVC-Client-Side-Validation

Resources