Git Product home page Git Product logo

kohana-formo's People

Contributors

bmidget avatar dfox288 avatar escalate avatar justus avatar leth avatar martinodf avatar mclowe-directnic avatar paulchubatyy avatar shadlaws avatar timmy8823 avatar zsoerenm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kohana-formo's Issues

Make Formo work with Jelly 1.0 API

Jelly is changing things up for the better for its 1.0 release.

I need to make Formo work with that version of Jelly. Since both will be using the same library and rules for validation, this will change Kohana-Formo-Jelly a bit.

Make subforms namespacing

$address = Formo::factory()
  ->add('street')
  ->add('zip');

$form->add('address', $address);

The items in the subform would be generated in html with the names:

name="address[street]"
name="address[zip]"

Another on '/html/option'

It happened again, but now with selects. Searches for /html/option view.

...
'status' => new Field_Enum(array(
             'choices' => array('draft', 'review', 'published'),
             'default' => 'published',
             'driver' => 'select',
             'options' => array('Draft'=>'draft', 'Review'=>'review', 'Publish'=>'published'),
          )),
          'user' => new Field_BelongsTo,
...

Throws for both of them

Kohana_View_Exception [ 0 ]: The requested view /html/option could not be found

SYSPATH\classes\kohana\view.php [ 252 ]

247      */
248     public function set_filename($file)
249     {
250         if (($path = Kohana::find_file('views', $file)) === FALSE)
251         {
252             throw new Kohana_View_Exception('The requested view :file could not be found', array(
253                 ':file' => $file,
254             ));
255         }
256 
257         // Store the file path locally

Question about subforms

is there a way to create a form with jelly to save a many-to-many relationship?
Example DB
table users {id, name}
table addresses {id, address, city}
table addresses_users {user_id, address_id}

Form displaying something like
name []
address[]
city[]

"'Container' class not found" error

There are two places where "Container" class is mentioned:

  1. file: classes/formo/validator/core.php , line: 455
  2. file: classes/formo/validator/trigger/core.php , line: 51

It seems like "Container" should be replaced by "Formo_Container".

API Changes

To make things altogether clearer, the API should be changed around a bit. Here are the basics:

Formo - The broadest interface
Formo_Container - Adds the ability to hold multiple fields
Formo_Validator - Formo-style validation
Formo_Form - A form/subform
Formo_Field - A field
Formo_Driver - Drivers for individual forms/subforms
Fomro_ORM - ORM drivers for ORM compatibility

The main change here is using the Formo class as the broad interface. Before it was what will become Formo_Form, and has had to double-act as the broad interface and a form/subform object.

Missing argument 2 exeption in validation

I am getting this error message when running validation with formo:

ErrorException [ Warning ]: Missing argument 2 for Kohana_Validate::max_length()
SYSPATH/classes/kohana/validate.php [ 71 ]

Here is my code


$user = Jelly::factory('user');

$user->subform(array('username', 'password'))
        ->add('submit', 'submit');

$user->subform->load()->validate();


Thank you for the help

What changed?

In the docs, this is the correct way to load a Jelly model:

$form = Formo::form()->orm('load', $user);

However, this returns:
ReflectionException [ 0 ]: Method Formo_Driver_Form::orm() does not exist

Incompatible with short_open_tag = off

In PHP 5.3 short_open_tag is disabled by default and I think it's also deprecated. All the default views use <?=, I think this should be changed to <?php echo for greater compatibility.

htmlentities() is not utf-8 safe

I observed some utf-8 encoded strings were messed up in output because of htmlentities(). It's used in a few places besides this one:

www/modules/formo/classes/formo/driver/checkbox/core.php
View file @ c22e25e... ... @@ -22,7 +22,7 @@ class Formo_Driver_Checkbox_Core extends Formo_Driver {
22 22 ->set('tag', 'input')
23 23 ->attr('type', 'checkbox')
24 24 ->attr('name', $this->field->parent()->alias().'[]')
25 - ->attr('value', htmlentities($this->render_field->val()));
25 + ->attr('value', HTML::entities($this->render_field->val()));
26 26
27 27 $parent_value = $this->render_field->parent()->val();
28 28

call_user_func_array() expects parameter 1 to be a valid callback

I am getting this error message by simple doing the fallowing that shows in the guide. Any ideas to fix it.

ErrorException [ Warning ]: call_user_func_array() expects parameter 1 to be a valid callback, class 'Ffield' does not have a method 'callback'
MODPATH/formo/classes/formo/core.php [ 106 ]

class Controller_Formo extends Controller {

public function action_index() 
{ 
    $user = Jelly::select('user', 52); 
    $form = Formo::factory() ->orm('load', $user); 
}

}

Post Filters

Add ost filtering to the pre_render area of drivers

Setting options from array appears to be broken

According to the docs

    $options = array
    (
        1 => 'Running',
        2 => 'Jumping',
        array
        (
            'alias' => 'swimming',
            'value' => 900
        )
    );
    $form->add_group('hobbies', 'select', $options, 2);

Should produce a select field like so:

    <select class = "" name = "hobbies"> 
    <option class = ""> 
    </option> 
    <option class = "" value = "1">Running</option> 
    <option class = "" value = "2">Jumping</option> 
    <option class = "" value = "900">swimming</option> 
    </select> 

But instead produces

    <select class = "" name = "hobbies"> 
    <option class = ""> </option> 
    <option class = "" value = "Running">1</option> 
    <option class = "" value = "Jumping">2</option> 
    <option class = "" value = "900">swimming</option> 
    </select> 

To get it to work as expected I had to reverse the array so that the value was the option's value and the key was the option text.

Checking checkboxes

There isn't currently a good way to make a checkbox checked by default.

I'm thinking an option has "checked" as true:

$options = array
(
  'item1' => array
  (
    'value' => 'somevalue',
    'checked' => TRUE,
  )
);

In addition to this, the method check (in the specific checkboxes and bool drivers) to check a field by its alias.

$form->hobbies->check(array('running', 'swimming'));

Formo breaks Jelly-Auth

Formo starts validating user model in complete_login function. And fails on password_confirm although we're just updating statistics.
Here's a piece of code I changed to work. But this is awful solution:

protected function complete_login($user)
{
    // Update the number of logins
    $user->logins += 1;

    // Set the last login date
    $user->last_login = time();

  // TODO: very-very-very bad
  $user->form->remove('password_confirm');
    // Save the user
  try
  {
     $user->save();
  }
  catch( Validator_Exception $e)
  {
     Notices::add('error',$e->getMessage().": ".print_r($user->form->errors(),true));
  }

    return parent::complete_login($user);
}

Here is default user_model given with jelly-auth:

 $meta->name_key('username')
           ->sorting(array('username' => 'ASC'))
           ->fields(array(
           'id' => new Field_Primary,
           'username' => new Field_String(array(
                   'unique' => TRUE,
                   'rules' => array(
                           'not_empty' => NULL,
                           'max_length' => array(32),
                           'min_length' => array(3),
                           'regex' => array('/^[\pL_.-]+$/ui')
                   )
           )),
           'password' => new Field_Password(array(
                   'hash_with' => array(Auth::instance(), 'hash_password'),
                   'rules' => array(
                           'not_empty' => NULL,
                           'max_length' => array(50),
                           'min_length' => array(6)
                   )
           )),
           'password_confirm' => new Field_Password(array(
                   'in_db' => FALSE,
                   'callbacks' => array(
                           'matches' => array('Model_Auth_User', '_check_password_matches')
                   ),
                   'rules' => array(
                           'not_empty' => NULL,
                           'max_length' => array(50),
                           'min_length' => array(6)
                   )
           )),
           'email' => new Field_Email(array(
                   'unique' => TRUE
           )),
           'logins' => new Field_Integer(array(
                   'default' => 0
           )),
           'last_login' => new Field_Timestamp,
           'tokens' => new Field_HasMany(array(
                   'foreign' => 'user_token'
           )),
           'roles' => new Field_ManyToMany
   ));

I think there is problem with model definition.

Excluding fields from form [Jelly and Formo fatal error - solved]

My vesion of Jelly should be 0.9.6.2

Jelly::factory($this->model)->form->render('html');
Jelly::factory($this->model)->subform(array('title','body'))->render('html');

Anyone of these throws «ErrorException [ Fatal Error ]: Call to a member function primary_key() on a non-object» in MODPATH\jelly\classes\jelly\core.php [ 341 ]. I debugged a bit and it seems that meta_alias function gets false instead of Jelly_Meta object.

Is there any way for these modules to work? Or what version of Jelly should i use?

i18n translation incorrect

Please see this patch. I think the pesudo params should not substituted before i18n translation.

www/modules/formo/classes/formo/validator/core.php 
View file @ 8c67da2...  ... @@ -508,13 +508,15 @@ abstract class Formo_Validator_Core extends Formo_Container {
508 508      
509 509      $values = Arr::merge(array(':value' => $this->val(), ':field' => $this->alias()), (array) $param_names);
510 510      
511     -    $message = strtr($message, $values);
512     -    
513 511      if (Kohana::config('formo')->translate === TRUE)
514 512      {
515 513        $values[':field'] = __($values[':field']);
516 514        $message = __($message, $values);
517 515      }
    516 +    else
    517 +    {
    518 +      $message = strtr($message, $values);
    519 +    }
518 520      
519 521      return $message;
520 522    }

Jelly save issue

Jelly and Kohana's validate are married together a bit too much, IMO.

Thoughts as Formo progresses toward 1.0

As Formo progresses toward its 1.0 mark, I wanted address a couple things:

Formo will require KOstache.

I expect this to be marginally controversial.

In my opinion, this will be a much cleaner, language-agnostic solution for creating actual view files instead of the current method of passing the render object to the view. I'm actually quite excited about this, though you will ultimately lose the ability to work with field objects with methods like $field->attr('id', 'someId'), for instance.

The nice thing about KOstache is you will not have to use it for the rest of the site if you don't want to.

Validation will change a bit.

Formo will not reach the 1.0 mark until Kohana implements Jon Geiger's (Validate changes)[http://dev.kohanaframework.org/issues/2966]. At that point Formo will use the validate library for all its validation.

The only difference here is Formo will not actually handle the validation. Syntax for setting rules, etc will be mostly the same. But you will catch Validate_Exception instead of Validator_Exception.

Jelly's gotta reach 1.0

Formo will not reach the 1.0 mark until Jelly reaches the same point. The reason is I want to support Jelly out of the box and let the community expand into other ORM drivers. At this point I personally do not have any interest in Kohana's stock ORM module.

Namespacing

I'm currently working on the implementation. All fields will be namespaced all the time. That's just how Formo will work.

Dynamic Fields

This is another issue that's been sitting unfinished for quite awhile. I am barely into this as well, but the specs are drawn. The way this works is you create a subform that is a template form. The template contains a field or fields and rules/filters/etc. that are projected onto any items added to the template subform.

The idea is you could easily add a dynamic field like "tags[]" that you can keep adding a tag, but likewise you could add an entire dynamic subform from a model definition.

Coupled with a bit of javascript, this will transform how I personally deal with forms and I can't wait for how much time this will save me

Playground Demo

Finally, the 1.0 tag will be coupled with a playground demo site. While I hope to keep excellent documentation, I still get many, many people asking for examples of Formo in use. The playground demo will demonstrate the basics of form creation & manipulation, orm integration, and I'm most excited about dynamic field demonstrations coupled with orm integration.

Support early load

Allow values to be loaded early. For instance:

$form->load($values)->add('username');

Load should always take precedence over defaults.

create_sub issue

I just pulled down the latest revision, but now I get this error.

ErrorException [ Fatal Error ]: Call to undefined method Formo_Driver_Form::find()

MODPATH/formo/classes/formo/driver/core.php [ 94 ]

89 $subform = Formo::factory($alias, $driver);
90
91 foreach ($fields as $field)
92 {
93 // Find each field
94 $field = $this->find($field);
95 // Remember the field's original parent
96 $last_parent = $field->parent();
97
98 // Add the field to the new subform
99 $subform->append($field);

Field_BelongsTo does not save

Field_BelongsTo displays correctly in the form, but on save submits NULL for a new record (and does not change for existing records). Is there anything that needs to be specified manually?

call_user_func_array() expects parameter 1 to be a valid callback

I am getting this error message by simple doing the fallowing that shows in the guide. Any ideas to fix it.

ErrorException [ Warning ]: call_user_func_array() expects parameter 1 to be a valid callback, class 'Ffield' does not have a method 'callback'
MODPATH/formo/classes/formo/core.php [ 106 ]

class Controller_Formo extends Controller {
public function action_index() {
$user = Jelly::select('user', 52);
$form = Formo::factory() ->orm('load', $user);
}
}

I manage to fix this error by adding the modifying your compatibility user model file. The role field should be Field_ManyToMany and the name or alias should be 'roles' instead of 'role', this solved the issue.

I also had to add the notes field to my user table for it to completely work. Am I correct with these changes or I was just missing something.

Thank you!

Attributes not working

Attributes stop working:

in the Jelly Model:
$user->form->attr('action', $_SERVER['REQUEST_URI'] );

or to a straight form:
$form = Formo::form()->attr('action', $_SERVER['REQUEST_URI'] );

Is the population driver select not implemented?

The following creates 2 select boxes. One for the enum and the other for the relation. However, they are just the empty select boxes. What am I doing wrong?

$user = Jelly::select('user', 1);
$form = Formo::form()->orm->load($user);

Jelly Object User

$meta->table('users')
->fields(array(
    'id' => new Field_Primary,
    'name' => new Field_String,
    'status' => new Field_Enum(array(
            'choices' => array('dead','alive'))),

    'mom' => new Field_BelongsTo(array(
        'foreign' => 'mom',
        'column' => 'id',
    )),
));


Jelly Object Mom

$meta->table('moms')
->fields(array(
    'id' => new Field_Primary,
    'first_name' => new Field_String,
    'last_name' => new Field_String,
));

Add custom validation messages files

Formo uses this validation message file by default messages/validate.php, currently there is no way to set custome validation messages files like for example if I want to use messages/user/login.php, messages/user/registration.php, etc.

Thank you!!

Allow editable flag

Set editable to FALSE to make view only render the value

$form->$field->set('editable', FALSE);
$form->field->get('editable');

Render function is not working.

Hi, I am trying to render my user form and I did this simple step bellow but all I get as output is:

open()?>
render('html')?>
render('html')?>
render('html')?>
close()?>

It seems like something is breaking the rendering function. Can you please check and see what is going on.

Here is my simple code:

class Controller_Formo extends Controller_Template {

public function action_index() {

    $user = Jelly::select('user', 5);

    $user->subform(array('email'))
    ->add('submit', 'submit');

    echo $user->subform->render('html');    
}

} // End Serivice Validate Controller

You also have some code typos in your userguide, under the Jelly Integration section. I will create a bug for it.

Thank you!!!

checkbox names / returned data

checkboxes added like so

$form->add('blah','checkbox','xy');

end up with a name value of "form[]", and any values are lost upon submitting.

Validation rules changes

Rules, trigger, filters will be added always with the ->rules($rule) method. It can be an array of rules or a single rule.

Since all validation rules are added via the same method, objects must be passed instead of just arrays.

Like this

$form->rule('email', Formo::rule('not_empty');

Or

$form->rule('username', Formo::rule(':model', 'unique', array('username')));

Or

$rules = array
(
  Formo::rule('not_empty'),
  Formo::rule(':model', 'unique', array('username'))
);

$form->rules('username', $rules);

Or

$rules = array
(
  'email' => Formo::rule('not_empty'),
  'email' => Formo::rule('email'),
  'username' => Formo::rule('not_empty'),
  'username' => Formo::rule(':model', 'unique', array('username'))
);

$form->rules($rules);

A very simple compatibility interface exists for non-full Jelly integration. In this way you can still define normal Validate rules in the model and Formo will interpret them.

Compatibility mode should be turned off when using full integration files.

Skip a field's rendering

This is different from ignore. Ignore simply ignores rules inside a field or subform.

But setting render to FALSE will not render the field. Rules still apply.

$form->$field->set('render', FALSE);
$form->$field->get('render');

Please update userguide

Please update the Jelly Integration section in the userguide since form is no longer used for calling subform, instead you need to use the subform method.

from:


// For the login form, we just need a blank record
$user = Jelly::factory('user');

// We can pull specific parts of the model by using $model->subform() instead of $model->form
$user->subform(array('username', 'password'))
    ->add('submit', 'submit');

$this->template->content = $user->form->render('html');

// Notice here we are working with just the user form object and not
// just $user->load()->validate. This is because we are working with
// a couple fields and not the entire user model
if ($user->form->load()->validate())
{
    if ($user->login())
        $this->request->redirect('admin');

    $user->form->error('invalid_login');
}


To this.


// For the login form, we just need a blank record
$user = Jelly::factory('user');

// We can pull specific parts of the model by using $model->subform() instead of $model->form
$user->subform(array('username', 'password'))
    ->add('submit', 'submit');

$this->template->content = $user->subform->render('html');

// Notice here we are working with just the user subform object and not
// just $user->load()->validate. This is because we are working with
// a couple fields and not the entire user model
if ($user->subform->load()->validate())
{
    if ($user->login())
        $this->request->redirect('admin');

    $user->subform->error('invalid_login');
}


and at the very bottom of the same section replace:


$user = Jelly::factory('user');

$user->subq array('email'))
    ->add('submit', 'submit');

$this->template->content = $user->form->render('html');

// Notice loading and validating against the form and not user
if ($user->form->load()->validate())
{
    // This would fail because in a typical user model,
    // username and password would at least be required
    // for a new record
    $user->savew();
}

with this


$user = Jelly::factory('user');

$user->subform array('email'))
    ->add('submit', 'submit');

$this->template->content = $user->subform->render('html');

// Notice loading and validating against the subform and not user
if ($user->subform->load()->validate())
{
    // This would fail because in a typical user model,
    // username and password would at least be required
    // for a new record
    $user->save();
}

Formo validation is returning the field value instead of "param1"

Formo validation is returning the field value as "param1" in the validation error messages:
"password must be at least dffgf characters long"
When it should be for example:
"password must be at least 6 characters long"

My user model is the jelly-auth default one and it has this rule:


'password' => new Field_Password(array(
                'hash_with' => array(Auth::instance(), 'hash_password'),
                'rules' => array(
                    'not_empty' => array(TRUE),
                    'max_length' => array(50),
                    'min_length' => array(6)
                )
            )),

Thanks!!!

Move all validation to Validator

Container shouldn't do any validation. Instead, Formo and Ffield extend Validator, which extends Container.

The render classes, like Formo_Render extend just Container, not Validator.

undefined method Model_User::form()

I am getting Call to undefined method Model_User::form() when trying to call the form method

public function action_index() {

    $user = Jelly::factory('user');


    $user->form(array('username', 'password'))
    ->add('submit', 'submit');


    echo $user->form->render('html');

    if ($user->load()->sent())
    {
        try
        {
            // Data is validated at save
            $user->save();
        }
        catch(Validate_Exception $e)
        {
            // Do something with $e
        }

    }
}

I already included the model and the jelly files for the full integration with jelly, It seems like there is no form() function in the module.

Can you please check this out.

Thank you!!

Jelly-Auth incompatible rule

I use jelly-auth which has a rule: 'not_empty' => array(TRUE),
this rule fails in pseudo_args(), since array_search($search, $params) returns 0 where $search = ':field' and $param = array(TRUE)
should it be array_search($search, $params, TRUE)?

Many container methods need to be moved to drivers

This is a simple change, but the container class should only do a few things at all.

The real magic should happen in the individual drivers, and that allows very complicated, custom drivers that do whatever you like.

For sure, val() needs to be removed from container.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.