Giter Site home page Giter Site logo

nette / forms Goto Github PK

View Code? Open in Web Editor NEW
481.0 53.0 145.0 2.43 MB

📝 Generating, validating and processing secure forms in PHP. Handy API, fully customizable, server & client side validation and mature design.

Home Page: https://doc.nette.org/forms

License: Other

PHP 88.78% HTML 1.47% JavaScript 9.08% Latte 0.67%
nette nette-framework php javascript forms html security safety validation

forms's Introduction

Nette Framework is a popular tool for PHP web development. It is designed to be as usable and as friendly as possible. It focuses on security and performance and is definitely one of the safest PHP frameworks.

Nette Framework speaks your language and helps you to easily build better websites.

The Quick Start tutorial gives you a first introduction to the framework by creating a simple database driven application.

Over 10 Yrs of Development

We have been developing Nette for over 10 years- and counting! Libraries we provide are therefore highly mature, stable and widely used. They are trusted by a number of global corporations and many significant websites rely on us.

Catching Bronze

We aim to create Nette as a fun and easy to use framework, that programmers can fall in love with. And we seem to be doing it well! We were rated as the 3rd most popular framework in a survey Best PHP Framework for 2015 by a well-know magazine SitePoint.

Security Is a Priority

There is nothing we care about more than security. That is why we had built Nette as the safest PHP framework. It had passed many audits with flying colours, it eliminates safety traps like XSS, CSRF and brings out ground-breaking methods.

Libraries & Framework

Nette consists of a number of handy standalone libraries, which can be used in any codebase, for example combined with WordPress or another framework. Careful, some of them are highly addictive! These are the components that Nette Framework is built on:

  • Application – The kernel of web application
  • Bootstrap – Bootstrap of your application
  • Caching – Cache layer with set of storages
  • Component Model – Foundation for component systems
  • DI – Dependency Injection Container
  • Finder – Find files and directories with an intuitive API
  • Database – Database layer
  • Forms – Greatly facilitates secure web forms
  • Http – Layer for the HTTP request & response
  • Latte – Amazing template engine
  • Mail – Sending E-mails
  • Neon – Loads and dumps NEON format
  • Php Generator – PHP code generator
  • Robot Loader – The most comfortable autoloading
  • Routing – Routing
  • Safe Stream – Safe atomic operations with files
  • Security – Provides access control system
  • Schema – User data validation
  • Tester – Enjoyable unit testing in PHP
  • Tracy – Debugging tool you will love ♥
  • Tokenizer – Source code tokenizer
  • Utils – Utilities and Core Classes

forms's People

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  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

forms's Issues

netteForms.js

Last version of netteForms.js break toggle functionality, if some inputs have no rules, but are in container with toggle, they never appear in form. (I guess it is becouse of rules, but not sure)

I will look at this on monday and investigate this little bit more deep, I know this is not ideal issue report.

addCondition - EQUAL

Hi,

na nize uvedene ukazce mi spatne funguje vnorena podminka EQUAL, jakmile porovnavaci hodnota je prazdne pole bez hodnot (toogle "from" je stale skryt). Jakmile odstranim podminku (EQUAL podminka neni vnorena):

->addConditionOn($form["namespace"], Forms\Form::EQUAL, 1)

tak vse funguje spravne.
Situaci momentalne resim zpusobem, ze misto prazdneho pole [] vracim pole s jednou hodnotou [-1]

$form->addSelect("namespace", "Namespace")
    ->setItems($this->model->getNamespacesArray())
    ->setPrompt("---");

$form->addSelect("reason", "Reason")
    ->setItems($this->model->getReasonsArray())
    ->addConditionOn($form["namespace"], Forms\Form::EQUAL, 1)
        ->toggle("reason-label")
        ->toggle("reason-input")
        ->addCondition(~Forms\Form::EQUAL,  $this->model->getNoNeedFrom()) // []
            ->toggle("from")
        ->endCondition()
        ->addCondition(~Forms\Form::EQUAL, $this->model->getNoNeedTo()) // [2, 5, 6]
            ->toggle("to")
        ->endCondition()
    ->endCondition();

netteForms.js mam aktualni verzi.

Examples (custom-control.php) wrong rendering while in groups

In method getControl() should be called parent::getControl().

Because $this->setOption('rendered', TRUE); needs to be called. (Shoud be called this without parent:::getControl() maybe?)

This control is renderd multipletimes when used like this:

$this->addGroup("Any group");
$this->addExampleComponent("xxx");

onValidate callback in Forms\Container not called when submitting Form

Really confusing about creating form containers is that you cannot use onValidate property for adding validation callbacks. It is never used. See following example.

class HomepagePresenter extends BasePresenter {

  protected function createComponentTestForm(){
    $form = new \Nette\Application\UI\Form;
    $form->addContainer("container"); // just exmaple, could be separate class
    $form["container"]->addText("foo", "Bar");
    $form["container"]->onValidate[] = array($this, "containerValidation");
    $form->addSubmit("send");
    $form->onValidate[] = array($this, "formValidation");
    return $form;
  }

  public function formValidation(){
        echo "validation from form ok"; // works
  }

   public function containerValidation(){
        echo "validation from container ok"; // doesn't work
   }
}

I understand that this callback is used by Form which extends Forms\Container, but if it cannot be used in "standalone" form container, shouldn't this property be in Form? Also the phpdoc makes the confusion even bigger. It says: "Occurs when the form is validated".


EDIT: removed workaround

netteForms.js: common js, amd

Since nette-forms is registered in bower repository, it would be really greate if netteForms.js could work with common js or amd environments.

Eg. I'm using browserify with gulp to build my js files. But it's little bit difficult with nette forms, because I have to use something like browserify-shim to actually simulate wanted behavior.

Prons:

  • In common js or amd environment, Nette object will not be in global object
  • Easy to use in these environments
  • Nette is trying to encourage everyone to not use global services like old Environment, so this is just another step 😉

Cons:

  • Pull request will be for whole file, because all code needs to be wrapped in function

Good example is at nprogress package.

Edit

So even browserify-shim doesn't work

Inconsistent Form::PATTERN

When I use back references in pattern rule (Form::PATTERN), it creates different behaviour on client side and server side in validation, because in Validator class, input pattern is bracked.

Example pattern: (.)\1{2,}
Different back reference:

  • Client side is \1
  • Server side is \2

Before I create PR, I would like to know, why pattern is bracked. There are two options: remove these bracket, or add to brackes (here, here).

use Nette\Forms\Form;

$form = new Form;
#$form->getElementPrototype()->novalidate = true;  // uncomment = validate by server side

$form->addText('name', 'Name:')
    ->addRule(
        Form::PATTERN, 
        'Please, write text with three same characters consecutively', 
        '(.)\1{2,}'
    );
$form->addSubmit('send', 'Register');
if ($form->isSuccess()) {
    echo '<h2>Form was submitted and successfully validated</h2>';

}
echo $form; // renders the form

reference bug reporting in czech forum: https://forum.nette.org/cs/25332-invert-regularniho-vyrazu#p168360

SelectBox validation

Is there any reason why SelectBox don't use standart validation via addRule? Can I prepare pull-request that replace overriding of validate method with addRule?

There is problem that when I forgot to render some select, I can't get input label in error message - becouse placeholders are not replaced...

Why TextInput::setDisabled(...) clear an input value?

Hi,

I am little confused from setDisabled method:

$form->addText(...)
  ->setValue('value')->setDisabled(); // setDisabled resets a value

// vs.

$form->addText(...)
  ->setDisabled()->setValue('value'); // but now setDisabled reset a value but value is set afterwards

Is there any reason why setDisabled resets a value?

CsrfProtection weakness

After security review done by external company one weakness has been found. Since base token is stored in session and session can have expiration days, there is possibility to store some tokens and use them for attacks (mainly on public computers - internet cafe).
Token should get regenerated after user login and logout. This can avoid most of illegal uses.

ids not generated for hidden inputs

in latest dev-master, hidden inputs have no html ids.

before we had e.g. frm-documentEditor-form-items now there's nothing

is this a bug or a new feature? it breaks all legacy js that works with these generated ids in our app

would suck big time to hunt down all hidden fields that are being used somewhere in js and manually change them

Continue loop - Minification problem

I know it is mainly my problem, but please can you replace this label reference with something else?
I am using jsshrink minification created by Jakub Vrána but his code is not possible to make it with this code. It does not know what to do with that part of code and shrink it in bad way => unfunction code.

Or, do you know ho to fix that on my side?

Thx :)

DefaultRender not accept group container wrapper

I think,

maybe in
DefaultFormRender->renderBody

should be
$container = $group->getOption('group', $defaultContainer);
instead of
$container = $group->getOption('container', $defaultContainer);

Broken JS initialization - Nette disables HTML5 validation

netteForms.js, line 515:

form.noValidate = 'novalidate';

Nette does not check whether given form is produced by Nette or other library and disables HTML5 validation for all forms. It is OK to do whatever Nette wants with forms created by Nette, but it must not touch other forms. When part of application uses another library, this behavior breaks things a lot.

Sollution: Do not set novalidate on entire form. Set it for individual inputs when nette attributes (e.g. data-nette-rules) are detected and processed. Or just don't use it when it is not required.

Redundant transmission of array parameter to form

If there is an array parameter of some presenter action (eg. function actionDefault(array $animals) and the form with equal named input (with array value, eg. $form->addMultiSelect('animals', ...)), then after the form si sent, values of that input are added to the form as hidden fields. In case of scalar input this is not happening and is should not occur either with array input.

When these hidden fields are present in the form, next send of the form has unexpected behavior.

See demonstration diff with screenshot in sandbox: nette/sandbox@master...VladaHejda:redundant-array-parameter

Toggle whole group, missing setOption('id', 'identificator') for groups

It's possible to set it, ofc. But default renderer does not work with it.

I guess, it should be possible to set for all HTML tags processed in rendering a form HTML id attribute.

In method DefaultFormRenderer::renderBody() shoud be a code like this:

$id = $group->getOption('id');
if ($id) {
    $container->id = $id;
}

When I solve how, I'll try to send pull request. :)

Default form rendering fails if source file is not in UTF8 encoding and uses rule with non-ascii message

When rendering form with following rule and the source file is saved in Windows-1250, it results to Fatal Error: Method Nette\Utils\Html::__toString() must not throw an exception. That's because Json::encode fails on exception Invalid UTF-8 sequence.

$form->addUpload('test', 'Test')
     ->addRule(Form::MAX_FILE_SIZE, 'Maximální velikost souboru je 1 MB', 1024);

I know it is probably expected to have all files in UTF8, but I have not found it in docs and therefore this might still be issue for beginners.

Proposal: Severity types for addError

I'd like to have ability to send severity type with the addError() which would be added as a class to the item.

Real world scenario would be forms rendered with bootstrap and displaying messages in alert, if I want to show just a warning alert, there is no way to do that natively using the Forms component.

Best way would be to rethink whole error system and use 'messages' instead.

$form->addMessage('This is my warning.','warning');
$email->addMessage('This email is invalid!','error');

To keep BC you could add alias to addError like this:

public function addError($msg)
{
    $this->addMessage($msg,'error');
}

Now of course this is just thinking out loud, having severity types for errors would be just enough.

Errors are not translated

Neither of those messages are translated:

$form->addError('error');
$form['input']->addError('error');

I'd suggest modify getErrors() in both Form and BaseControl:

with something like this:

$errors = array_unique(array_merge($this->errors, parent::getErrors());

if ($this->getTranslator()) {
    $translatedErrors = array();
    foreach ($errors as $error) {
        $translatedErrors[] = $this->getTranslator()->translate($error);
    }
    $errors = $translatedErrors;
}

return $errors;

Unable to set custom class for label of RadioList item

Use case: custom renderer with method:

public function renderControl(Nette\Forms\IControl $control)
{
    ...
    if ($control instanceof \Nette\Forms\Controls\RadioList) {
         $control->getLabelPrototype()->class("my-class", TRUE);
    }
}

This custom class is not propagated to final <label> tag. The problem is in method RadioList::getControl() on line 92. Here we can find only this array for label attributes:

array('for:' => $ids)

On the other hand, CheckboxList works fine.

Form::IS_IN rule support

Is there a reason why IS_IN is internally mapped to EQUAL rule and does not have custom implementation?

ValidationScope: User unfriendly implementation

Hello,
I'd like to ask, could we come up with some way to rework disabling validation scope for selected fields?

Currently if you have 17 fields and one of them is AJAXified <select>, you have to do this:

$form->addSubmit('submit')->setValidationScope([
        $form['name'], $form['email'], $form['password'], $form['phone'], $form['ic'],
        $manage['isBanned'], $manage['isApproved'], $account, $address,
]);

Best way would be to disable this per-field.

Typo in Readme

Looks like there is a typo in the README unless I miss something on the following paragraph?

"Every multiple-choice, select boxe and similar are checked for forged values upon validating. Sounds good? Let's try it out."

Is it trying to say boxes?

Translate error message for control

Hi

I use translator for translating form labels, inputs, etc. After i used addError method with path to translation message like this $form['password']->addError('loginForm.password.wrongPassword'); I get untranslated message in template. Others translating of labels, descriptions, etc. works fine.

JS: failing max_length validation on checkbox list with exactly 1 item

Minimal code in sandbox

protected function createComponentForm()
{
    $form = new Form();
    $form->addCheckboxList('list', NULL, [
        1 => 'one',
    ])->addRule(Form::MAX_LENGTH, 'max is %d', 20);

    $form->addSubmit('submit', 'Submit');
    $form->onSuccess[] = function() {
        dump('success');
    };

    return $form;
}

val.length is undefined (val == TRUE) in netteForms.js

min_length is affected as well

Unfortunately I can't help you with js

macro <label n:name> does not print label value

$form->addText('field', 'My field');

//template
<form n:name="testForm">
<label n:name="field"></label>
<input n:name="field">
</form>

//generated HTML code
<label for="frm-testForm-field"></label>
<input id="frm-testForm-field" type="text" name="field">

Label is empty

Client-side validation of filled radiolist does not work in IE9

It still shows an alert even when a radio button is selected while submitting the form.

The issue is reproduced in this commit.

It is caused by these two lines in netteForms.js:

    } else if (elem.name && !elem.form.elements.namedItem(elem.name).tagName) { // multi element
        return Nette.getValue(elem.form.elements.namedItem(elem.name));

When I revert them to the pre-2.3 version, it works fine:

    } else if (elem.form.elements[elem.name] && !elem.form.elements[elem.name].nodeName) { // multi element
        return Nette.getValue(elem.form.elements[elem.name]);

But I am not 100% sure this is the right solution because I don't know what was the reasoning behind using namedItem and tagName instead of nodeName.

You can test the sandbox in IE9 with a virtual machine from here.

AJAX field with the same name as persistent parameter behaves unpredictible

When u try to send an form via AJAX with the field named the same as a persistent parameter, application will try to save that value to the persistent state although the form has been sent by the POST method and it's fields have NOTHING to do with the persistent state.

Interesting is that within normal POST (non AJAX) this is not happening.

Workaround is to name those fields with some different names.

maintainance

do you plan to maintain this repo long term?
do you have any idea when David plans to create repo for this?

(this issue is about bower repo, d.g.)

Partial rendering of RadioList is very strict to default value

This form definition

$form->addRadioList('test', 'Test', [
    '1' => "one",
    '2' => "two",    
]);
$form->setDefaults(['test' => '1']);

with following rendering

{foreach ['1', '2'] as $key}
    {input test:$key}
    {label test:$key /}
{/foreach}

will not check the default radiolist value due to strict comparison here. Maybe the $key might be fixed by the same trick as used here. What do you think?


Example is quite artificial, but when the arrays are generated somewhere, it is not so obvious what is happening...

toggle() on RadioList not working in Internet Explorer 11

protected function createComponentTestForm()
{
    $form = new Nette\Application\UI\Form();

    $form->addGroup();

    $form->addText('field', 'Visible field')->setRequired('Fill %label');

    $form->addRadioList('switch', NULL, array('hide' => 'Hide', 'show' => 'Show'))
        ->setDefaultValue('hide')
        ->addCondition(\Nette\Application\UI\Form::EQUAL, 'show')
        ->toggle('show-container');

    $form->addGroup()->setOption('container', \Nette\Utils\Html::el('div')->id('show-container'));

    $form->addText('hiddenField', 'Hidden field')
        ->addConditionOn($form['switch'], \Nette\Application\UI\Form::EQUAL, 'show')
        ->setRequired('Fill %label');

    $form->addGroup();

    $form->addSubmit('send', 'Add');

    return $form;
}

show-container is properly hidden at the start, but is not visible when second radio is selected.

Javascript validation on hiddenField also not working.

In Firefox and Chrome everything works as expected.

Sanitizing Form::DATA_KEYS data type

Hi! Thanks for good library.

In class Nette\Forms\Form declared 4 data type constants: DATA_TEXT, DATA_LINE, DATA_FILE, DATA_KEYS.

I create custom control and in overrided loaddHttpData method I set data type to DATA_KEYS.

$this->setValue($this->getHttpData(Nutnet_Form::DATA_KEYS));

But Nette\Forms\Helpers::sanitize method throws exception Nette\InvalidArgumentException('Unknown data type'), because for DATA_KEYS not exist sanitizer.

Field named like extraFields[image] and contains array(e.g. extraFields[image][name]). If named array parameter contains array value, library not sanitize this, it's seen in Nette\Forms\Helpers::extractHttpData method.

if (substr($htmlName, -2) === '[]') {
   // if key named, code here not executed
    ...
} else {
    // this is not sanitize DATA_KEYS
    return static::sanitize($itype, $data);
}

This is normally or you forgot add sanitizer and it's bug? (Nette/Forms 2.3)

Manually rendered form in snippet - cannot find components

Hi,
I have this latte code:

<div n:snippet="webinjectResolver" class="snippet">
    {form webinjectElementResolveForm}
        {label sign_type}{/label}{control sign_type}
        ...
    {/form}
</div>

which is compiled into this:

    //
    // block _webinjectResolver
    //
    if (!function_exists($_b->blocks['_webinjectResolver'][] = '_lbd34f2d71df__webinjectResolver')) { function _lbd34f2d71df__webinjectResolver($_b, $_args) { foreach ($_args as $__k => $__v) $$__k = $__v; $_control->redrawControl('webinjectResolver', FALSE)
    ?>                    <?php echo Nette\Bridges\FormsLatte\Runtime::renderFormBegin($form = $_form = $_control["webinjectElementResolveForm"], array()) ?>
                            <?php if ($_label = $_form["sign_type"]->getLabel()) echo $_label ; $_l->tmp = $_control->getComponent("sign_type"); if ($_l->tmp instanceof Nette\Application\UI\IRenderable) $_l->tmp->redrawControl(NULL, FALSE); $_l->tmp->render() ?>

And I'm getting exception message Nette\InvalidArgumentException - Component with name 'sign_type' does not exist.

I think there is problem with $_control variable - it's MyPresenter instead of webinjectElementResolveForm.

If I render control with tag, it works as expected: <select n:name="sign_type"></select> Any suggestions?

Associative arrays not handled correctly

I've noticed that the Form::IS_IN rule on select boxes is not handled correctly. I'd imagine being able to just put the same array I used to build up the select into the rule, but it's neither parsed to a json valid array nor flattened, so netteForms.js would be able to correctly validate the selectbox.

Danger setValue

Hello,

before some time I've been fixing a bug in our project which was caused by using setValue on input instead of setDefaultValue, so typed value by user was overwritten. After investigation I've found same bug across our projects and made by a lot of different developers.
This moved me to think about setValue method which is confusing. Is there any use-case, when it can't be protected? I think, that it's only used in creating custom inputs and then protected or at least @internal annotation should help with eliminating this mistake. Custom inputs are extending input so protected is ok.
In my opinion is this more confusing, than eg. method callbacks so we should think about it.

Latte macros {label} and {input} ignores custom form renderer

Let's have a form with custom renderer:

$form->setRenderer(new CustomFormRenderer());

and this latte template:

{form customForm}
    {label name /}
    {input name}
{/form}

Than CustomFormRenderer is not applied while rendering label and input.

Here is a quick workaround:

{form customForm}
    {var $label = $form->renderer->renderLabel($form[name])}
    {$label}
    {var $control = $form->renderer->renderControl($form[name])}
    {$control}
{/form}

Something like this should be generated automatically.

Form::fireEvents() calls onError only when it has multiple success handlers

it should be something like this

if ($this->onSuccess) {
    foreach ($this->onSuccess as $handler) {
        if (!$this->isValid()) {
            break;
        }
        $params = Nette\Utils\Callback::toReflection($handler)->getParameters();
        $values = isset($params[1]) ? $this->getValues($params[1]->isArray()) : NULL;
        Nette\Utils\Callback::invoke($handler, $this, $values);
    }
}

if (!$this->isValid()) {
    $this->onError($this);
}

because now, when I have only one success handler and add errors in it, the onError is not called

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.