PopupForm

The PopupForm is used to load and post a form in a popup. It can be initialized using Html.Awe().InitPopupForm and opened using awe.open js function or Html.Awe().OpenPopup helper. It loads the content from the .Url(string) provided and when the user clicks ok, the form will be posted, if the result of the post is view/string (usually when ModelState not valid) the content of the popup will be replaced with the post result, when the result is a json object the popup will close, if the PopupForm has a success function defined the json object will be passed that function.

You can see the PopupForm being used in all of the Crud demos (Grid), also in the Wizard Demo. In most Crud demos the call to Html.Awe().InitPopupForm is being wrapped in a custom helper Html.InitCrudPopupsForGrid which calls this helper multiple times (for Create, Edit, Delete).

PopupForm with Success function assigned

PopupFormDemo/Index.cshtml
@(Html.Awe().InitPopupForm(new PopupFormOpt
{
Name = "createDinner",
Height = 400,
Url = Url.Action("Create", "DinnersGridCrud"),
OnSuccess = "created"
}))

@Html.Awe().Button().Text("Create").OnClick(Html.Awe().OpenPopup("createDinner"))

<script type="text/javascript">
function created(result, popup) {
alert('dinner created');
}
</script>
Demos/Grid/DinnersGridCrudController.cs
/// </summary>
/// parameters for Edit, Delete controller Actions need to remain called "id", that's how they are set in GridUtils.cs ( "params:{{ id:" );
/// or in MapToGridModel additionally to o.MyId add another property Id = o.MyId
/// and for the action columns (edit, delete btns) you can either specify the MyId property (e.g. GridUtils.EditFormatForGrid("DinnersGrid", "MyId"));
/// change the Bind = "MyId" (if you have an Id column),
/// Note: If your Key Property is not "Id" (but "MyId"), you need to change the GridModelBuilder.Key = "MyId" in GridGetItems and in the view
/// <summary>
public class DinnersGridCrudController : Controller
{
private static object MapToGridModel(Dinner o)
{
return
new
{
o.Id,
o.Name,
Date = o.Date.ToShortDateString(),
ChefName = o.Chef.FullName,
Meals = string.Join(", ", o.Meals.Select(m => m.Name)),
BonusMeal = o.BonusMeal.Name
};
}

public IActionResult GridGetItems(GridParams g, string search = "")
{
var query = Db.Dinners
.Where(o => o.Name.Contains(search)).AsQueryable();

var model = new GridModelBuilder<Dinner>(query, g)
{
KeyProp = o => o.Id, // needed for api select, update, tree, nesting, EF
Map = MapToGridModel,
};

return Json(model.Build());
}

public IActionResult Create()
{
// make sure to use "return PartialView" for PopupForm/Popup views
// this will ignore _viewstart.cshtml so that you don't use the _Layout.cshtml and reload all the scripts
return PartialView();
}

[HttpPost]
public IActionResult Create(DinnerInput input)
{
return save(input);
}

public IActionResult Edit(int id)
{
var dinner = Db.Dinners
.Single(o => o.Id == id);

var input = new DinnerInput
{
Id = dinner.Id,
Name = dinner.Name,
ChefId = dinner.Chef.Id,
Date = dinner.Date,
MealsIds = dinner.Meals.Select(o => o.Id),
BonusMealId = dinner.BonusMeal.Id
};

return PartialView("Create", input);
}

[HttpPost]
public IActionResult Edit(DinnerInput input)
{
return save(input);
}

private IActionResult save(DinnerInput input)
{
if (!ModelState.IsValid) return PartialView("Create", input);

var isCreate = !input.Id.HasValue;

var ent = isCreate ? new Dinner() :
Db.Dinners
.First(o => o.Id == input.Id);

ent.Name = input.Name;
ent.Date = input.Date.Value;
ent.Chef = Db.Find<Chef>(input.ChefId);

// ToList req for EF
ent.Meals = Db.Meals
.Where(o => input.MealsIds.Contains(o.Id)).ToList();

ent.BonusMeal = Db.Find<Meal>(input.BonusMealId);
ent.Organic = input.Organic ?? false;

if (isCreate)
{
Db.Add(ent);
}

// json obj = success for the popupform, id is used to flash the row
return Json(new { Id = ent.Id });
}

public IActionResult Delete(int id)
{
var dinner = Db.Find<Dinner>(id);

return PartialView(new DeleteConfirmInput
{
Id = id,
Type = "dinner",
Name = dinner.Name
});
}

[HttpPost]
public IActionResult Delete(DeleteConfirmInput input)
{
Db.Delete<Dinner>(input.Id);

// delete PopupForm's success function will use the Id to animate the row
return Json(new { Id = input.Id });
}
}
DinnersGridCrud/Create.cshtml
@model AweCoreDemo.ViewModels.Input.DinnerInput
@using (Html.BeginForm())
{
using (Html.Awe().BeginContext())
{
<div class="eform">
<div class="earea">
@Html.EditorFor(o => o.Name)
@Html.EditorFor(o => o.Date)
@Html.EditorFor(o => o.ChefId)
</div>
<div class="earea">
@Html.EditorFor(o => o.BonusMealId)
@Html.EditorFor(o => o.MealsIds)
</div>
</div>
}
}

Open without initialization

Open the PopupForm in javascript without prior initialization.
PopupFormDemo/Index.cshtml
@Html.Awe().Button().Text("Open Popup").OnClick("openPopupAwe()")
<script>
function openPopupAwe() {
awe.open("popupAwe",
{
// PopupForm specific properties
type: 'popupForm',
useDefaultButtons: false, // don't use default Ok, Cancel buttons
useFormData: true, // will make ajax file uploads work
success: created,

// same properties as for the popup
url: '@Url.Action("Create", "DinnersGridCrud")',
btns: [
{
text: 'Submit',
ok: 1, // add okbtn class
action: function () {
$(this).find('form').submit();
}
},
{
text: 'Close',
action: function () {
$(this).data('api').close();
}
}],
height: 300,
width: 700,
title: 'Create Dinner',
modal: true,
//content: 'hello world'
//top: true,
//close: function() { console.log('popup closed'); },
//params: { p: 123 }
//outClickClose: true,
//popupClass: 'class1',
//fullscreen: true,
//dropdown: true
});
}
</script>

Sending client side parameters to server on content load

Value sent to the server action that returns the popup's content:
PopupFormDemo/Index.cshtml

@(Html.Awe().InitPopupForm(new PopupFormOpt
{
Name = "PopupFormParams",
Url = Url.Action("PopupWithParameters"),
ParameterFunc = "setParams"

}
.Button("Help", "helpClick")
.Parent("txtParam1")
.Parameter("p1", 15)))

@(Html.Awe().Button().Text("Open Popup")
.OnClick(Html.Awe().OpenPopup("PopupFormParams").Params(new { Id = 123 })))

<script>
function setParams() {
return { a: "hi", b: "how are you" };
}

function helpClick() {
awe.flash($(this).find('.msg1').html('help clicked'));
}
</script>
Demos/Helpers/PopupFormDemoController.cs
public IActionResult PopupWithParameters(int? id, string parent, int p1, string a, string b)
{
ViewData["parent"] = parent;
ViewData["p1"] = p1;
ViewData["a"] = a;
ViewData["b"] = b;
ViewData["id"] = id;
return PartialView();
}

[HttpPost]
public IActionResult PopupWithParameters()
{
return Json(new { });
}
PopupFormDemo/PopupWithParameters.cshtml
parameter set in the OpenPopup call: id = @ViewData["id"]
<br />
value of the parent: @ViewData["parent"] <br />
<br />
value of the p1 parameter: @ViewData["p1"] <br />
<br />
parameters sent by js function set using ParameterFunc:<br />
a = @ViewData["a"] <br />
b = @ViewData["b"] <br />

@using (Html.BeginForm())
{
}

<div class="msg1"></div>

Submit confirmation using OnLoad func

Confirmation dialog before posting a valid form.
PopupFormDemo/Index.cshtml
@(Html.Awe().InitPopupForm(new PopupFormOpt
{
Name = "confirmedPopup",
Height = 200,
MaxWidth = 400,
Url = Url.Action("PopupConfirm"),
UseDefaultButtons = true,
OnLoad = "regConfirm"
}))

@Html.Awe().Button().Text("Open popup").OnClick(Html.Awe().OpenPopup("confirmedPopup"))

<script>
function regConfirm() {
var $popup = this.d;
var $form = $popup.find('form');
$form.on('submit', function (e) {
if (!confirm("Are you sure ?")) {
return false;
}
});
}
</script>

Confirm close

Confirming popup close when closing it via the Cancel or X button, valid form posts are not confirmed.
PopupFormDemo/Index.cshtml
@(Html.Awe().InitPopupForm(new PopupFormOpt
{
Name = "confirmClosePopup",
Height = 200,
PopupClass = "needConfirm",
OnSuccess = "logConfClose",
Url = Url.Action("PopupConfirm")
}))

@Html.Awe().Button().Text("Open confirm close popup").OnClick(Html.Awe().OpenPopup("confirmClosePopup"))
<div id="logConfClose"></div>
<script>
function logConfClose(res) {
$('#logConfClose').html(res.Name);
}

$(function() {
// registering a global confirm close for all popups that have "needConfirm" popup class
$(document).on('awebfclose', function (e, opt) {
var pdiv = $(e.target);

// opt.post = close popup after successful form post
if (!pdiv.closest('.needConfirm').length || opt.post || opt.force) return;

// flag that we can set in 'awebfclose', tells the popup not to close
opt.noclose = true;

var pp = pdiv.data('o');
awe.open('confirmClose', {
title: 'Confirm close',
content: '<div style="padding: 1em;">Are you sure you want to close this popup ?</div>',
height: 200,
width: 500,
modal: true,
btns: [
{
text: "Yes",
ok: 1,
action: function () {
$(this).data('api').close();
pp.cx.api.close({ force: true });
}
},
{
text: "No",
action: function () {
$(this).data('api').close();
}
}]
});
});
});
</script>

Note: besides the features shown on this page the PopupForm also inherits the features of the Popup




Comments