Hello World from the ExampleController viewModelFormBindingAction action Normal Action View Binding
ViewModel Binding with tag helpers
The controller is responsible for tying the view model and its data to the view. In the ViewModel Binding example, using the return $this->viewModel(); provided view model binding behaviour. With annotated view models, the controller needs to be provided with the location of the actual view model and a reference to the data used to populate the view model.
The return $this->viewModel("People/Person", PeopleService::get()); tells the controller that there is an annotated view model inside the application/viewModels/People/PersonViewModel.class.php file, and that the PeopleService::get() method returns the needed data.
The second parameter, of return $this->viewModel(); accepts an object with data. The action that accepts the postback is able to using the (object)$_POST to repopulate the view model. Therefore the viewModelFormBindingPostAction() needed a little, extra help in filling in the blanks of the $_POST values to complete the annotations listed in the view model.
Below the ExampleController has been shortened for the purposes of this example.
<?php
class ExampleController extends FrontController
{
/**
* URL: Example/viewModelFormBinding/
* Alias: view-model-annotated-binding-example/
*
* @annotation DependenciesLocations(People)
* @annotation DependencyInjection(PersonService, PersonViewModel)
*
* @return View
*/
public function viewModelFormBindingAction()
{
$this->createExampleDisplayTemplate("Annotated ViewModel Binding Example", "_viewModelAnnotatedBinding");
$this->view->content = "Hello World from the <b>ExampleController viewModelFormBindingAction</b> action";
$this->view->addJavascript("public/js/example.js");
return $this->viewModel("People/Person", PeopleService::get());
}
/**
* Accepts postback from Example/viewModelFormBinding/
* Accepts postback from /view-model-annotated-binding-example/
*
* @annotation DependenciesLocations(People)
* @annotation DependencyInjection(PersonService, PersonViewModel)
*
* @return View
*/
public function viewModelFormBindingPostAction()
{
$this->createExampleDisplayTemplate("Annotated ViewModel Binding Example", "_viewModelAnnotatedBinding");
$this->view->content = "Hello World from the postback of <b>ExampleController viewModelFormBindingPostAction</b> action";
$this->view->addJavascript("public/js/example.js");
$_POST['genders'] = PeopleService::genders();
$_POST['languages'] = PeopleService::languages();
$_POST['province'] = PeopleService::provinces();
return $this->viewModel("People/Person", (object)$_POST);
}
} /*end of class ExampleController*/ Below the application/viewModels/People/PersonViewModel.class.php has its properties using the @ annotation declarations within the phpdoc.
<?php
class Person
{
/**
* @annotation Id(FirstName)
* @annotation Display(First Name)
*
* @var string
*/
public $firstName;
/**
* @annotation Id(LastName)
* @annotation Display(Last Name)
*
* @var string
*/
public $lastName;
/**
* @annotation Id(EmailAddress)
* @annotation Display(Email Address)
* @annotation Type(email)
*
* @var string
*/
public $emailAddress;
/**
* @annotation Id(Description)
* @annotation Display(Description)
*
* @var string
*/
public $description;
/**
* @annotation Id(Province)
* @annotation Display(Province)
* @annotation Value(provinceId)
*
* @var array
*/
public $province;
/**
*
* @var integer
*/
public $provinceId;
/**
* @annotation Id(Gender)
* @annotation Display(Sex)
* @annotation Type(radio)
* @annotation Options(genders)
*
* @var string
*/
public $sex;
/**
*
* @var array
*/
public $genders;
/**
* @annotation Id(Languages)
* @annotation Display(Languages)
* @annotation Type(multiple)
* @annotation Value(language)
*
* @var array
*/
public $languages;
/**
*
* @var array
*/
public $language;
} /*end of class Person*/ Below the application/models/People/PersonService.class.php provides the view model with default values.
<?php
class PeopleService
{
/**
* Get a single Person object
*
* @return Person
*/
public static function get()
{
$person = new Person();
$person->firstName = "Romayne";
$person->lastName = "Eastmond";
$person->emailAddress = "info@calgarywebdev.com";
$person->description = "Hello World";
$person->provinceId = 1;
$person->province = PeopleService::provinces();
$person->languages = PeopleService::languages();
$person->sex = "male";
$person->genders = PeopleService::genders();
$person->language = array(1);
return $person;
}
/**
* Get a list of genders
*
* @return array
*/
public static function genders()
{
return array(
"male" => "Male",
"female" => "Female",
"other" => "Other"
);
}
/**
* Get a list of languages
*
* @return array
*/
public static function languages()
{
return array(
0 => "C#",
1 => "PHP",
2 => "Javascript",
3 => "CSS",
4 => "HTML",
5 => "SQL"
);
}
/**
* Get a list of provinces
*
* @return array
*/
public static function provinces()
{
return array(
0 => "British Columbia",
1 => "Alberta",
2 => "Saskatchewan",
3 => "Manitoba",
4 => "Ontario",
5 => "Quebec",
6 => "New Brunswick",
7 => "Nova Scotia",
8 => "Prince Edward Island",
9 => "Newfoundland and Labador"
);
}
} /*end of class PeopleService*/ Below the application/views/forms/Person/person.php, is an include file that contains the person form. Take note of the tag helper syntax which is inspired by ASP.NET MVC 6 approach to view model binding.
The php-label-for, php-input-for, and php-value-for rewrite the annotations provided by the view model and changes them into valid HTML elements. Each tag helper accepts a value corresponding to the name of a property of the view model.
<form method="post">
<div class="form-group">
<label php-label-for="firstName"></label>
<input php-input-for="firstName" php-value-for="firstName" class="form-control" />
</div>
<div class="form-group">
<label php-label-for="lastName"></label>
<input php-input-for="lastName" php-value-for="lastName" class="form-control" />
</div>
<div class="form-group">
<label php-label-for="emailAddress"></label>
<input php-input-for="emailAddress" php-value-for="emailAddress" class="form-control" />
</div>
<div class="form-group">
<label php-label-for="description"></label>
<textarea php-input-for="description" php-value-for="description" class="form-control"></textarea>
</div>
<div class="form-group">
<label php-label-for="sex"></label>
<div>
<input php-input-for="sex" php-value-for="sex" />
</div>
</div>
<div class="form-group">
<label php-label-for="province"></label>
<select php-input-for="province" php-value-for="province" class="form-control"></select>
</div>
<div class="form-group">
<label php-label-for="languages"></label>
<select php-input-for="languages" php-value-for="languages" class="form-control"></select>
</div>
<div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-info">Submit</button>
</div>
</form> Raw Post output only available after form has been submitted.