how to change html view using binding in angular 6 - binding

I have an angular 6 project , I have a component for book like this
<div class="col-md-4 agileinfo_single_left">
<img id="BigBookView" src="public/books/images/{{book.photo}}" alt=" " class="img-responsive">
</div>
<div class="col-md-8 agileinfo_single_right">
<h1>{{book.name | uppercase}}</h1>
<h2>Series: {{book.seriesName}}</h2>
<h3>Author: {{book.author}}</h3>
<h4></h4>
<div class="w3agile_description">
<h4>Summary : {{book.summary}}</h4>
</div>
<div class="snipcart-item block">
<div class="snipcart-thumb agileinfo_single_right_snipcart">
<h4 class="m-sing">Price: {{book.price}}$</h4>
<h4 class="m-sing">Seller: {{book.seller}}</h4>
</div>
<div class="snipcart-details agileinfo_single_right_details">
<form action="#" method="post">
<fieldset>
<input type="submit" name="submit" value="Add to cart" class="button">
</fieldset>
</form>
</div>
</div>
all of this is inside a modal and every time I choose a book and the modal is opened and suppose to show the book data in this html.
This is the component type script
export class BigBookViewComponent implements OnInit {
#Input()
public book:Book = new Book();
constructor() { }
ngOnInit() {
}
public changeBook(newBook: Book) {
console.log(this.book);
this.book = newBook;
}
}
using the function changeBook I send to this component a new book to show but the html and the UI don't chagne, even though I can see in the console.log(this.book); line that the book is indeed being sent.
How can I change the html to show a diffrent book?

You should assign the book on ngOnInit method.
When assigning in the constructor the single instance of the component will keep the original book.

Related

How do I redirect from an MVC Post Action back to the bootstrap popup modal partial view where the post came from?

How do I redirect from an MVC Post Action back to the bootstrap popup modal partial view where the post came from?
Here is the PartialView sitting in the Bootstrap modal popup on the page.
It has a div with a validation taghelper waiting for any model errors.
#model CreateRoleViewModel
<div class="panel panel-primary partialModalFormDivs">
#Html.Partial("_ModalHeader",
new ModalHeader
{
Heading = "ADD ROLE",
glyphiconClass = "glyphicon glyphicon-random"
}
)
<div class="panel-body">
<div asp-validation-summary="All" class="text-danger"></div>
<form asp-action="CreateRole" method="post">
<div class="form-group">
<label asp-for="RoleName"></label>
<input asp-for="RoleName" class="form form-control" />
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Create</button>
<a asp-action="Index" class="btn btn-default">Cancel</a>
</div>
</form>
</div>
</div>
It posts to this action:
[HttpPost]
public async Task<IActionResult> CreateRole(CreateRoleViewModel createRoleViewModel)
{
if (ModelState.IsValid)
{
IdentityRole role = new IdentityRole(createRoleViewModel.RoleName);
IdentityResult result
= await _roleManager.CreateAsync(role);
if (result.Succeeded)
{
return RedirectToAction("Index");
}
else
{
foreach (IdentityError error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
}
return View(createRoleViewModel);
}
I can return a PartialView like this at the end:
return View("_CreateRole", createRoleViewModel);
But then the whole page is cleared and this partial is returned with no layout file.
How can I return the results back to the modal popup window.
I understand the problem and the current behavior. But has anyone else solved this?
I think what you want to do is an ajax post and then just return a partial view and replace the form. The form should be inside a container div with an id that is used to replace its contents with the ajax post result. To do this you need to include the jquery unobtrusive ajax script which will auto wire the ajax based on the data-* attributes on the form as shown below
<div class="panel-body">
<div asp-validation-summary="All" class="text-danger"></div>
<div id="resultcontainer">
<form asp-action="CreateRole" method="post"
data-ajax="true"
data-ajax-method="POST"
data-ajax-mode="replace"
data-ajax-update="#resultcontainer"
>
<div class="form-group">
<label asp-for="RoleName"></label>
<input asp-for="RoleName" class="form form-control" />
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Create</button>
<a asp-action="Index" class="btn btn-default">Cancel</a>
</div>
</form>
</div>
</div>
and don't forget to return a partial view
return PartialView(createRoleViewModel);

ASP.NET MVC input validation to allow only two digit numbers on a model property that is string type

The input values can be any two digit numbers of the form 00, 01,...09,10,11,....19,20,...,99 etc. But following is not working. User can still enter abc and no client side validation occurs. Of course the error occurs after the form is posted since SQL Server does not except, for example, abc in a char(2) column. It needs to occur during client side validation as explained here. What I may be missing?
Note: Not using data type as number since it would force 01 to 1, 02 to 2 ,... etc. It has to be of the type 01, 02, ...,etc.
Model Snapshot:
Column[TypeName = "char(2)"]
[RegularExpression(#"^[0-9]{2,2}$", ErrorMessage = "Must be two digits numbers"), StringLength(2)]
public string TestCode { get; set; }
Views\Shared\Components\Default.cshtml
<form asp-controller="TestController" asp-action="TestAction" method="post">
<div asp-validation-summary="All" class="text-danger"></div>
....
....
<div class="form-group">
<label asp-for="TestCode" class="col-md-2 control-label"></label>
<div class="col-md-2">
<input asp-for="TestCode" class="form-control" />
<span asp-validation-for="TestCode" class="text-danger"></span>
</div>
</div>
<button type="submit" name="submit" value="TestVal">Save</button>
</form>
UPDATE
I'm using Visual Studio 2015 with latest update -3 and ASP.NET Core 1.1. The project is created using their default Web App Core template that includes built-in JQuery, JQuery-Validation, bootstrap etc. Following is the snapshot of the html generated in Google Chrome Dev Tool.
Snapshot of Google Chrome Dev Tool:
<label class="col-md-2 control-lable" for="TestCode">TestCode<label>
<div class="col-md-2">
<input class="form-control" type="text" id="TestCode" name="TestCode" value>
<span class="text-danger field-validation-valid" data-valmsg-for="TestCode" data-valmsg-replace="true"></span>
</div>
UPDATE 2:
When user clicks on Tab2 of the Main View (with Bootstrap Tabstrip), an Ajax code (shown below) displays a Partial view in Tab2 content pane that displays a list of various buttons. When user clicks on one of those buttons, same controller (shown below) calls a ViewComponent that displays the view in question (please see this ViewComponent view before UPDATE section above).
Controller:
[HttpGet]
public IActionResult TestAction(string calledFrom, int SelectedOrderYear, int id)
{
....
return ViewComponent("Test_VC", new { id = id });
}
Main View with Bootstrap Tabs:
#model MyProj.Models.TestViewModel
....
....
<ul class="nav nav-tabs">
<li id="menu1ID" class="active"><a data-toggle="tab" href="#menu1">Menu 1</a></li>
<li id="menu2ID"><a data-toggle="tab" href="#menu2">Menu 2</a></li>
</ul>
<div class="tab-content">
<div id="menu1" class="tab-pane fade">
</div>
<div id="menu2" class="tab-pane fade">
</div>
</div>
#section scripts
$('#myTabstripID li').click(function () {
var li_id = $(this).attr("id");
$.ajax({
url: '#Url.Action("TestAction", "TestController")',
data: { calledFrom: li_id },
contentType: 'application/json',
dataType: 'html',
type: 'GET',
cache: false,
success: function (data) {
if (li_id == 'menu1ID')
$('#menu1').html(data);
else if (li_id == 'menu2ID')
$('#menu2').html(data);
}
});
});

How to bind ngFormModel in angular2 using Dart?

The following works in a form (the form is displayed)
.html
<form (ngSubmit) = "onSubmit()"
#nameForm = "ngForm">
{{diagnostic}}
<div class = "mdl-card mdl-shadow--3dp layout horizontal wrap">
<div class = "mdl-card__title">
<h2 class = "mdl-card__title-text">Name</h2>
</div>
<div
class = "mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input
required
type = "text"
[(ngModel)] = "name.first"
ngControl = "first"
#first = "ngForm"
(input)="onInputHandler($event)"
class = "mdl-textfield__input ng-valid"
id = "first">
<label
class = "mdl-textfield__label"
for = "first">First</label>
<span [hidden] = "isFirstValid"
class = "mdl-textfield__error">{{firstErrorMsg}}</span>
</div>
<div class =
"mdl-card__actions mdl-card--border">
<button id = "startButton"
class = "mdl-button mdl-js-button mdl-button--raised mdl-button--accent mdl-js-ripple-effect"
>Submit
</button>
<br>
<button class = "mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
Button All
</button>
</form>
Trying to follow the example at Forms and Validation in Angular 2.0,
I cannot get the UI to display by changing the first line of the form to
<form (ngSubmit) = "onSubmit()"
[ngFormModel]="form" #f="form">
{{diagnostic}}
..
With the change the browser simply does not display anything as if it cannot parse the markup - the error is actually shown in pub-serve or debug mode.
Transform TemplateCompiler on epimss_ng2_reg|lib/components/name_component.ng_meta.json threw error: Template parse errors:
There is no directive with "exportAs" set to "form" ("
<div [hidden] = "isSubmitted">
<form (ngSubmit) = "onSubmit()"
[ng-form-model]="form" [ERROR ->]#f="form">
{{diagnostic}}
<div class = "mdl-card mdl-shadow--3dp layout horizontal wrap">
"): NameComponent#12:31
....
Why is this not working?
Seems this was changed since when the blog post was created.
NgForm is now exported as ngForm instead of form.
[ngFormModel]="form" #f="ngForm">
It's correct in the GitHub source but not in the blog post.
Full component according to the example in the blog post in Dart
#Component(selector: 'form-element')
#View(template: '''
<h1>form-element</h1>
<form (ngSubmit)="onSubmit()" [ngFormModel]="form" #f="ngForm">
<div>
<div class="formHeading">First Name</div>
<input type="text" id="firstName" ngControl="firstName">
<div class="errorMessage" *ngIf="f.form.controls['firstName'].touched && !f.form.controls['firstName'].valid">First Name is required</div>
</div>
<div>
<div class="formHeading">Street Address</div>
<input type="text" id="firstName" ngControl="streetAddress">
<div class="errorMessage" *ngIf="f.form.controls['streetAddress'].touched && !f.form.controls['streetAddress'].valid">Street Address is required</div>
</div>
<div>
<div class="formHeading">Zip Code</div>
<input type="text" id="zip" ngControl="zip">
<div class="errorMessage" *ngIf="f.form.controls['zip'].touched && !f.form.controls['zip'].valid">Zip code has to be 5 digits long</div>
</div>
<div>
<div class="formHeading">Address Type</div>
<select id="type" ngControl="type">
<option [value]="'home'">Home Address</option>
<option [value]="'billing'">Billing Address</option>
</select>
</div>
<button type="submit" [disabled]="!f.form.valid">Save</button>
<div>
<div>The form contains the following values</div>
<div>
{{payLoad}}
</div>
</div>
</form>
''')
class FormElement {
ControlGroup form;
String payLoad;
FormElement(FormBuilder fb) {
form = fb.group({
"firstName": ['', Validators.required],
"streetAddress": ['', Validators.required],
"zip": [
'',
Validators.compose([ZipValidator.validate])
],
"type": ['home']
});
}
void onSubmit() {
payLoad = JSON.encode(this.form.value);
}
}

Unobtrusive JQuery Validation not working in popup PartialViews [duplicate]

This question already has an answer here:
Required field validations not working in JQuery Popup MVC 4
(1 answer)
Closed 7 years ago.
I have the following a partial view in asp.net 5 mvc 6 project. The partial view is shown as a jquery ui dialog and is loaded dynamically when the user clicks a button in the parent view page.The issue is that the Unobtrusive JQuery Validation does not work after I enter invalid entires and clicked submit.
I have done all the procedures needed to make Unobtrusive JQuery Validation work and it works in Non partial views.
Here is my code
my partial view name EquipmentEditTemplate.cshtml
#model MyProject.Models.EquipmentViewModel
#*<form role="form" name="FormPost" asp-controller="Asset" method="post" asp-action="SaveEq" data-ajax="true" id="FrmGrid_grdLocation1" class="FormGrid form-horizontal" style="width:477px;height:703px;">*#
#*<form asp-controller="Asset" asp-action="SaveEq" method="post" style="width:600px;height:703px;" class="form-horizontal" >*#
<div class="FormError bg-danger" style="display:none;"></div><div class="tinfo topinfo"></div><div class="modal-body">
<div style="margin-left:15px;">
<div class="form-group">
<label asp-for="EquipmentID" class="col-sm-2 control-label">Equipment ID:</label>
<div class="col-sm-10">
<input asp-for="EquipmentID" class="FormElement form-control" />
<span asp-validation-for="EquipmentID" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<label asp-for="Email" class="col-sm-2 control-label">Email:</label>
<div class="col-sm-10">
<input asp-for="Email" class="FormElement form-control" />
</div>
</div>
<div class="form-group">
<label asp-for="Department" class="col-sm-2 control-label">Department:</label>
<div class="col-sm-10">
<input type="text" id="Department" name="Department" value="#Model.Department" role="textbox" class="FormElement form-control">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign in</button>
</div>
</div>
</div>
</form>
I have the code below in the main view as shown I have included the validation scripts in there equipment.cshtml
#{
ViewData["Title"] = "Equipment";
}
<h2>#ViewData["Title"].</h2>
<h3>#ViewData["Message"]</h3>
#section scripts{
#{await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
<script src="~/js/equipment.js" type="text/javascript"></script>
}
I have my model class defined as follows
public class EquipmentViewModel
{
[Required]
public int EquipmentID { get; set; }
[EmailAddress]
public string Email{ get; set; }
public int Description{ get; set; }
}
}
When you've loaded a form in to your DOM dynamically then add the below line at the end of your partial view.
$(document).ready(function() {
$.validator.unobtrusive.parse($('#yourform'));
});

Form validations lost when included in template

I have a directive, which successfully includes a template in my AngularJS app using Rails 4.2 and angular-rails-templates.
Everything seems to be working fine, even the two way data binding, although there is one exception. Form validation using AngularJS is lost if I include the <form> tag inside the template file.
When I run this in my local environment, Angular includes the template, display it on my main page. if you enter data the two way data binding updates, but the form validation is not handled by Angular, it uses HTML5 browser validation instead.
Any help appreciated, I assume there is some common thing I am missing, like how / when the template is inserted?
I have prepared a working demo at Plnkr, the same code executes without incident on Plnkr, but not when using Rails.
JS:
var app = angular.module('app', ['templates']);
app.config([
'$httpProvider', function($httpProvider) {
return $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
}
]);
app.run(function() {
return console.log('angular app running');
});
app.directive('serviceRequest', function() {
return {
restrict: 'E',
templateUrl: 'service-request.html',
controller:function() {
this.request = {};
this.addService = function(request) {
//$http request
this.request = {};
}
},
controllerAs: 'service'
};
});
The HTML template (service-request.html):
<form name="myForm" novalidate="">
<div>
serviceForm is {{myForm.$valid}}
</div>
<fieldset>
<legend>Service Request</legend>
<h1>{{service.request.number}} <small>{{service.request.reported | date}}</small></h1>
<div class="row">
<div class="small-12 medium-10 large-10 small-centered">
<div class="row">
<div class="small-3 columns">
<label for="right-label" class="right">Number:</label>
</div>
<div class="small-9 columns">
<label>
<input type="text" ng-model="service.request.number" placeholder="small-9.columns" required/>
</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="small-12 medium-10 large-10 small-centered">
<div class="row">
<div class="small-3 columns">
<label for="right-label" class="right">Reported:</label>
</div>
<div class="small-9 columns">
<input type="text" ng-model="service.request.reported" placeholder="small-9.columns" required/>
</div>
</div>
</div>
</div>
<input type="submit" ng-disabled="myForm.$invalid ">
</fieldset>
</form>

Resources