MVC 5 Webpage save button display label - asp.net-mvc-5

I have a controller with a create ActionResult which saves data in a webform.
When the information in saved in the form i would like to display a label saving the data was saved.
Is this possible to do?
Thanks

Ofcourse it is possible to do. Something along these lines should work fine. You can apply the same principles for an error message. The reason i put the if to check whether the view bag is null is because that bootstrap class will put an empty green block on the screen if its null
razor view
#if(ViewBag.Success != null){
<p class="alert alert-success">#ViewBag.Success</p>
}
mvc Post
[HttpPost]
public ActionResult ActionName(FormData fd){
//... save your form
ViewBag.Success = "You have successfully saved something."
Return View();
}

Related

how to transfer data from one view to another in net core 2.0

I would like to create another model transferring some data from previous view. Actually I need to transfer key to save relation between objects. What are the best practices?
In my case I have one view representing a model of car and I need to start a next view representing a part containing the foreign key to the car. How to do this?
I need to transfer some attributes from one model/view to another model/view while creating. I mean passing foreign key need to keep relation in a different view(model). I tried to use the form but the web page dosen't appear to fill in the other attributes.
<form asp-action="CreateFromFirstView" asp-controller="secondControler" style="display:inline;">
<input type="hidden" name="KeyID" value="#Model.KeyID" />
<button type="submit" class="btn btn-imary">CreateFromFirstView</button>
</form>
You can create a ViewModel and send to other view the object like a Model.
Example
public ActionResult Index()
{
var vm = new VehicleDetailsViewController();
return View(vm);
}
[HttpPost]
public ActionResult Index(VehicleDetailsViewController vm)
{
//Validation something wrong
if (!ModelState.IsValid) return View(vm);
//Make what you want with all OK
return View("AllOk");
}

ASP.NET MVC Core - Displaying an Enum property in a View (NOT related to a DropDownList)

I want to display an Index style View featuring an HTML table that I populate from my #model, a List<MyViewModel>.
The MyViewModel class has a property called Status, which is a custom enum I've defined like so:
public enum MarketingEmailStatus
{
Queued,
Sending,
Sent
}
When I attempt to display that property in my View like so ...
...
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayForModel(modelItem => item.Status)
</td>
...
I get an error (both in Intellisense and at run time):
Cannot convert lambda expression to type 'object' because it is not a delegate type
I tried to do item.Status.ToString() to no avail.
No doubt, I could probably take an alternative approach (i.e., just change the ViewModel to represent Status as a string and resolve this prior to sending to the view), but this feels like such a simple scenario that it should be possible. And yet after an hour of searching I've not found any solutions (other than those related to DropDownLists for which there seems to be some #Html helper methods available.)
I see two problems with directly using #item.Status:
It won't respect the "display values" of those enums e.g. instead of
"Code Sample", it would show "CodeSample".
It doesn't take into account the localization.
This looks like a very promising solution for such scenarios, in my opinion.
You can obviously just use the extension methods if point 2 is not your concern as below:
public static class EnumExtensions
{
public static string GetDisplayName(this Enum enumValue)
{
FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString());
var displayAttribute = fi.CustomAttributes.FirstOrDefault(c => c.AttributeType == typeof(DisplayAttribute));
if (displayAttribute == null) return enumValue.ToString();
return displayAttribute.NamedArguments.FirstOrDefault(a => a.MemberName == "Name").TypedValue.Value.ToString();
}
}
In ASP.NET Core, especially in my own web application — which we both somehow have been upgrading constantly since ASP.NET Core 2.0 days — what I did was just used the variable name from Model and did a # on it, ASP.NET Core 2.0 took care of the rest. It is quite surprising to me, as to why you are still using these Html helpers, and not the best of what ASP.NET has to offer. :-) And yes, for select element, there is a special ASP.NET Core tag helper, which takes the model and in the case of a simple text display you can do #propertyName and it will be properly written for you.
Let me share the necessary model content with you,
public class Foo {
// Other properties
public int Views { get; set; }
public PostType PostType { get; set; }
// Other properties.
}
The enum is like this,
public enum PostType { Article, Video, CodeSample, Ebook, Other }
Now, on the View page I do the following after capturing the Model,
<!-- Content here. -->
<p>#post.PostType has #post.Views views.</p>
<!-- Content here. -->
And there, it automatically prints the string containing the enum value.
As you can see, the last line in the paragraph shows Article has 6 views. Which was the response for the item that I had selected. Rest of the content in the image can be ignored.
Now, as to just give an idea of a table, this would perfectly work — and it does work for my dashboard panel in the web app.
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Status</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>#item.Id</td>
<td>#item.Name</td>
<td>#item.Status</td>
</tr>
}
</table>
There is no need to bring in lambdas for such a simple task — I mean, no need for #Html helper, because Razor is enough and smart too.

Is it possible in Orchard to dynamically change HTML in a shape right before rendering?

This is the markup for Content.ThumbnailSummary.cshtml, a custom DisplayType I use to render ContentItems as clickable thumbnails with their contents absolutely positioned over them.
#using Orchard.Utility.Extensions;
#{
var contentTypeClassName = ((string)Model.ContentItem.ContentType).HtmlClassify();
}
<a class="content-item #contentTypeClassName thumbnail-summary">
#Display(Model.Header)
<div class="thumbnail-summary-inner">
#Display(Model.Content)
</div>
#Display(Model.Footer)
</a>
The problem is that out of the box most Parts and Fields get rendered as links or paragraphs containing links, and nested <a> tags mess up DOM rendering pretty badly in most browsers. A ThumbnailSummary should never contain any links.
I could create alternates for every field and part, or I could remove everything by default in placement and only add rules for specific cases as I need them. But that would be pretty tedious and defeats a lot of the benefits of placement, so I was hoping I could somehow strip or replace all <a> tags in code only for shapes with this DisplayType.
I've been looking in this direction but I'm not sure if it's viable:
public class Shapes : IShapeTableProvider
{
public void Discover(ShapeTableBuilder builder)
{
builder.Describe("Content")
.OnDisplaying(displaying =>
{
if (displaying.ShapeMetadata.DisplayType == "ThumbnailSummary")
{
// Do something here???
}
});
}
}
You are almost right, instead of a provider add a class that inherits from Orchard.DisplayManagement.Implementation.ShapeDisplayEvents or implement IShapeDisplayEvents yourself.
I've done this myself to remove certain functionality from admin area that cannot be disabled via feature or permission.
The code should look like this
public class MyShapeDisplayEvents : Orchard.DisplayManagement.Implementation.ShapeDisplayEvents
{
public override void Displayed(Orchard.DisplayManagement.Implementation.ShapeDisplayedContext context)
{
if (context.Shape is Orchard.DisplayManagement.Shapes.Shape)
{
Orchard.DisplayManagement.Shapes.Shape lShape = (Orchard.DisplayManagement.Shapes.Shape)context.Shape;
if (lShape.Metadata.Type == "Layout")
{
string lChildContent = context.ChildContent.ToHtmlString();
// do something with the content like removing tags
context.ChildContent = new System.Web.HtmlString(lChildContent);
}
...

Accessing submit-button's data attributes in ASP.Net Core MVC controller?

I have a submit button, with the following HTML:
<button type="submit" class="back-button" data-direction="back">Back</button>
The controller method is defined like this:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(SearchModel searchModel, string SearchBy, string dataDirection)
{
// Code removed for simplicity...
}
When I click the button, my Model is populated, but the dataDirection property is not populated.
What is the correct way to access those data attributes?
This is not a ASP .NET MVC issue.For submit buttons, browsers only send the value of the "value" attribute when the form is submitted. The button's name is used as the parameter name and the value is used as the parameter value.
If you want to send additional parameters with the form based on which button is clicked, you have to use Javascript to listen for the 'click' event of the button and add your custom parameters to the post data or set some hidden field values before submission.
Easiest way is to put a hidden field in your form with name "Direction", listen button click set its value to 'back' or 'next'. And if you have a default value for the direction or you want the last direction value to be set to the hidden field after a postback, you may put a "Direction" property on your model.
Below code shows how you do it with jQuery:
<input type="hidden" name="Direction" value="#Model.Direction" id="fldDirection" />
<script type="text/javascript">
$("[type='submit']").on('click', function() {
if ($(this).data('direction')) {
$("#fldDirection").val($(this).data('direction'));
}
}
</script>

Craeting Custom Widget in Orchard 1.7

I am new to Orchard. So please forgive me if there is anything looking silly!
I want to create a custom widget for my Orchard website to encourage visitors to sign up for my Newsletter service. I have seen there is an option of using HTML widget but I want to create a new widget type like "Newsletter" which I shall use conditionally at AsideFirst block.
Is this possible to do? I only want to grab visitor's Name and Email address, and the form submission will be done using an action controller.
Do I have to create this widget through by-hand coding in VS? In fact I want to this way, not through the Orchard admin console.
Seeking for help. Any suggestion please?
Edit:
I have managed to create the widget following Sipke Schoorstra's suggestion. The area where I want to display the widget is now showing along with the the title I set from admin at the time of adding it to a zone. But the content (form elements) I created in the view is not displaying.
The View: (Views/NewsLetterSignupPart/NewsletterSignup.cshtml)
#model Emfluence.Intrust.Models.NewsLetterSignupPart
#{
ViewBag.Title = "Newsletter Signup";
}
#using (Html.BeginForm("NewsletterSignup", "NewsLetter", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="row-fluid">
<div class="span6">
<label>Name</label>
<input type="text" name="txtNewsletterUserName" required maxlength="50" style="width: 95%" />
<label>Email</label>
<input name="txtNewsletterUserEmail" type="email" required maxlength="85" style="width: 95%" />
<button class="btn pull-right">Submit</button>
</div>
</div>
}
Migration.cs
public int UpdateFrom15()
{
ContentDefinitionManager.AlterTypeDefinition(
"NewsletterWidget", cfg => cfg
.WithPart("NewsLetterSignupPart")
.WithPart("CommonPart")
.WithPart("WidgetPart")
.WithSetting("Stereotype", "Widget")
);
return 16;
}
NewsLetterSignupPart.cs
public class NewsLetterSignupPart : ContentPart<NewsletterSignupRecord>
{
[Required]
public string Name
{
get { return Record.Name; }
set { Record.Name = value; }
}
[Required]
public string Email
{
get { return Record.Email; }
set { Record.Email = value; }
}
}
And NewsletterSignupRecord.cs
public class NewsletterSignupRecord : ContentPartRecord
{
public virtual string Name { get; set; }
public virtual string Email { get; set; }
}
Where I am doing wrong?
The Custom Forms module is great if you don't want or need to code something yourself. In case you do want to handle form submissions yourself without using Custom Forms, this is what you could do:
Create a custom module
Create a migrations class that defines a new widget content type (see the docs for details on how to do this. Note: you don't need to create a custom part. You don't even need to create a migrations file to create a content type - you could do it using a recipe file. The nice thing about a migration though is that it will execute automatically when your module's feature is enabled).
Create a view specific for content items of your widget type (e.g. Widget-Newsletter.cshtml).
Inside of this view, write markup that includes a form element and input elements. Have this form post back to your controller.
Create your controller.
In the /admin interface, click Modules, on the Features` tab search for Custom Forms and click Enable. This will add a new Forms admin link on the left.
Next, create a custom content type (under Content Definition) called Newsletter, and add two fields (of type Text Field) called Name and E-mail.
Finally, click Forms and add a new Custom Form. Give it a title: this will be the default URL to access e.g. "Newsletter Form" will have a URL of /newsletter-form by Orchard defaults. Under Content Type select your newly created content type, Newsletter, from the dropdown. Customize anything else you want on this page, and click Publish Now
If you want to make this a widget, edit the content type and add the Widget Part. Create a layer with the rules you need and you can add the "Newsletter" widget to any zone you need on that layer.

Resources