Is it possible to pass multiple arguments to model.bind? Something along the lines model.bind="{car: carObject, factory: factoryObject}" ?
I would like to use it in a snippet like
<div class="column">
<compose
view="./car.html"
view-model="../../view-models/cars"
model.bind="{car: $parent.$parent.car, factoryIndex: $index}">
</compose>
</div>
and in the VM to handle them like
public activate(car, factoryIndex) {
this.data = car;
this.factoryIndex= factoryIndex;
}
The way you are binding your model you are creating an object that contains both a property for car and factoryIndex - so if you use it like this in your activate function it should work:
public activate(data) {
this.data = data.car;
this.factoryIndex = data.factoryIndex;
}
Related
I have such an example of a model:
class BirthdayModel {
List birthdays;
BirthdayModel({
#required this.birthdays,
});
factory BirthdayModel.fromJson(json){
return BirthdayModel(birthdays: json['data']);
}
Map<String, dynamic> toJson() {
return {
'birthdays': birthdays,
};
}
}
I want to transfer multiple models into one method:
exampleMethod(model: BirthdayModel);
and then in this method call the constructors or methods of the passed class
exampleMethod(#required model){
return model.fromJson(data);
}
Is it possible to do this?
Not the way you write it.
You cannot pass a class as argument. Even type arguments only pass types, so you cannot use static members that way.
What you can do is:
T exampleMethod<T>(T createModelFromJson(dynamic json)){
return createModelFromJson(data);
}
and call it as :
var birthday = exampleMethod(BirthdayModel.fromJson);
There is no way to access the fromJson programmatically - it's not an instance method so there is no interface for it. Static methods must be accessed explicitly.
(I'm ignoring dart:mirrors because you probably won't have access to those).
In a SYMFONY FORM (ORM is not use (PDO is used for DB query instead)).
I have a class MyEntityType in which the buildForm function has:
$builder->add('my_attribute',ChoiceType::class,array(
'choices'=>$listForMyAttribute,
'multiple'=>'true',
'attr'=>array('data-native-menu'=>'false'),
'label'=>'Multiple Select on my attribute'
));
My attribute is an array of an entity named MyEntity which has:
/**
* #Assert\NotBlank()
*/
private $myAttribute;
With a getter and a setter for that variable $myAttribute.
When I submit the form in the Controller, it doesn't pass the validation check and logs this error:
Unable to reverse value for property path "myAttribute" : Could not find all matching choices for the given values.
When I start to look for solution around this error message, it leads to something named "How to Use Data Transformers" in SYMFONY Cookbook; And it seems a solution would involve to create new Class and write a lot of code for something that one should be able to by-pass in a much straight forward way.
Does anyone have an idea?
My problem was that my array $listForMyAttribute was defined in the buildForm() function and its definition was relying on some conditional.
The conditional to make the array were met when this one was displayed for the first time.
After pushing the submit button, the buildForm was regenerated in the Controller, this second time, the condition were not met to make the array $listForMyAttribute as it was on the first display. Hence the program was throwing a "contraint not met error" because the value submited for that field could not be find.
Today I face exactly the same problem. Solution is simple as 1-2-3.
1) Create utility dummy class DoNotTransformChoices
<?php
namespace AppBundle\DataTransformer;
use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface;
class DoNotTransformChoices implements ChoiceListInterface
{
public function getChoices() { return []; }
public function getValues() { return []; }
public function getPreferredViews() { return []; }
public function getRemainingViews() { return []; }
public function getChoicesForValues(array $values) { return $values; }
public function getValuesForChoices(array $choices) { return $choices; }
public function getIndicesForChoices(array $choices) { return $choices; }
public function getIndicesForValues(array $values) { return $values; }
}
2) Add to your field the following additional option:
...
'choice_list' => new DoNotTransformChoices,
...
3) Congratulations!
I am trying to learn symfony.. can someone please tell me if there is a similar method like renderErrorText()? because this method renderError() outputs html with an ul/li tag. I just want the text of the error and not its html.
You need to define your own decorator. The renderError use a preformatted format to display an html renderer.
Create a file like lib/form/sfWidgetFormSchemaFormatterMyFormatter.class.php:
<?php
class sfWidgetFormSchemaFormatterMyFormatter extends sfWidgetFormSchemaFormatter
{
protected
$rowFormat = '',
$helpFormat = '%help%',
$errorRowFormat = '%errors%',
$errorListFormatInARow = " <ul class=\"error_list\">\n%errors% </ul>\n",
$errorRowFormatInARow = " <li>%error%</li>\n",
$namedErrorRowFormatInARow = " <li>%name%: %error%</li>\n",
$decoratorFormat = '',
$widgetSchema = null,
$translationCatalogue = null;
And inside this class, you can define how to format and render an error.
Then, you will need to define this class a the default formatter for your form. If this is about your frontend environment, in apps/backend/config/frontendConfiguration.class.php:
class frontendConfiguration extends sfApplicationConfiguration
{
public function configure()
{
sfWidgetFormSchema::setDefaultFormFormatterName('MyFormatter');
}
}
Or if you want to it to be global to your project, in config/ProjectConfiguration.class.php:
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
sfWidgetFormSchema::setDefaultFormFormatterName('MyFormatter');
}
}
You will find :
a documented example here
an example for twitter bootstrap
I am trying to implement a "bulk" insert for hasMany. And got it 90% there, but hit a hiccup with my polyclass design. I have a model like
class Parent {
static hasMany = [references: Reference]
}
class Reference {
static belongsTo = [parent: Parent]
String name
}
class ConcreteReference extends Reference{
String childName
}
I was able to get the create working(defined by creating records) by having markup like
<form action='reference/1/edit>
<input name='references[0].name' value='name1' />
<input name='references[0].childName' value='childName1' />
<input name='references[1].name' value='name2' />
<input name='references[1].childName' value='childName2' />
</form>
But the issue is it always creates the concrete type(class='domain.Reference'), so "child name is always null.
I used:
def edit(def id){
def parent = Parent.get(id)
//i actually clear all the old references first (didn't show that code)
parent.properties = params
parent.save(flush:true)
}
How can I either specify the "concrete type"( I tried a hidden value of class it didn't work) or is there an easy way to loop through params.reference[idx] create it and then add it to Parent?
hopefully that is clear, let me know if you need any clarification.
My manual way of parsing params(not I hard code ConcreteReferences, but i was able to group the params):
def refRegex = /^([a-zA-Z]+\[\d+\])/
for (ref in params.groupBy { it -> it.key.find(refRegex)}.findAll{it.key}){
//this will be like references[0]: [references[0].name : 'test', etc]
//for each one create a FreeFormReference
def _ref = new ConcreteReference(ref.value.collectEntries{it -> [it.key.replace(ref.key + '.', ''), it.value]})
log.info('created reference ${_ref}')
parent.addToReferences(_ref)
}
How do I write options so I can generate it into an HTML select? The problem with this is "options" needs a set, not an array
Here is everything I have. I know the naming convention is bad, and I will fix that, but for right now I've been on this issue for days now.
Controller Class
import org.springframework.dao.DataIntegrityViolationException
import grails.plugin.mail.*
class EmailServiceController {
static defaultAction = "contactService"
def contactService() {
def options = new ArrayList()
options.push("Qestions about service")
options.push("Feedback on performed service")
options.push("Other")
options.push("Why am I doing this")
options
}
def send() {
sendMail(){
to "mygroovytest#gmail.com"
from params.email
subject params.subject
body params.information
}
}
}
Domain class
class EmailService {
static constraints = {
}
}
g:select call from the gsp
<g:select name = "subject" from = "${options}" noSelection="Topic"/>
also tried the following with "${selectOptions}" instead of "${options}" with no luck
def selectOptions() {
def options = new ArrayList()
options.push("Qestions about service": "QAS")
options.push("Feedback on performed service":"FoPS")
options.push("Other":"Other")
options.push("Why am I doing this":"WHY")
return options
}
Ok, I think I might know what is going on here. The missing piece to the question is what gsp is being called. Here is the appropriate way:
class EmailServiceController {
def contactService() {
def options = ["Qestions about service", "Feedback on performed service", "Other"]
// assumes you are going to render contactService.gsp
// you have to push the options to the view in the request
[options:options]
}
}
And then in contactService.gsp you would have:
<g:select name="subject" from="${options}" noSelection="['Topic': 'Topic']"/>
Your options is neither an array nor map. There is a syntax error. That's why you have only one option in your select. You need to enter either a real list or a map, like that:
def selectOptions() {
def options = [:]
options["Qestions about service"] = "QAS"
options["Feedback on performed service"] = "FoPS"
[options:options]
}
Using a map you can use it in the view like this:
<g:select name="subject" from="${options.entrySet()}"
optionValue="key" optionKey="value"
noSelection="['Topic': 'Topic']"/>
You need to use double quotes in your tags, not single quotes. With single quotes, you're just passing a String that looks like '${options}' instead of passing a GString with the value of options.
<g:select name="subject" from="${options}" noSelection="Topic"/>
In addition, assuming you're calling the contactService action, you need to return options instead of returning options.push("Other"). push() returns a boolean, which means the implicit return of contactService is the boolean result of push() instead of options.