SlideShare ist ein Scribd-Unternehmen logo
1 von 74
Downloaden Sie, um offline zu lesen
Instant
Dynamic Forms
      with
             #states
Konstantin KĂ€fer
                   2




    2006
#states   3
4
Anatomy of a state
                                                         5




$form['payment_information'] = array(
   '#type' => 'fieldset',
   '#title' => t('Payment information'),
   '#collapsible' => TRUE,
   '#collapsed' => TRUE,
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
Anatomy of a state
                                                         5




$form['payment_information'] = array(
   '#type' => 'fieldset',
   '#title' => t('Payment information'),
   '#collapsible' => TRUE,
   '#collapsed' => TRUE,
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
Anatomy of a state
                                                         5




$form['payment_information'] = array(
   '#type' => 'fieldset',
   '#title' => t('Payment information'),
   '#collapsible' => TRUE,
   '#collapsed' => TRUE,
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
Anatomy of a state
                                                         5




$form['payment_information'] = array(
   '#type' => 'fieldset',
   '#title' => t('Payment information'),
   '#collapsible' => TRUE,
   '#collapsed' => TRUE,
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
Anatomy of a state
                                                         5




$form['payment_information'] = array(
   '#type' => 'fieldset',
   '#title' => t('Payment information'),
   '#collapsible' => TRUE,
   '#collapsed' => TRUE,
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
Anatomy of a state
                                                         5




$form['payment_information'] = array(
   '#type' => 'fieldset',
   '#title' => t('Payment information'),
   '#collapsible' => TRUE,
   '#collapsed' => TRUE,
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
Anatomy of a state
                                                         5




$form['payment_information'] = array(
   '#type' => 'fieldset',
   '#title' => t('Payment information'),
   '#collapsible' => TRUE,
   '#collapsed' => TRUE,
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
Anatomy of a state
                                                         5




$form['payment_information'] = array(
   '#type' => 'fieldset',
   '#title' => t('Payment information'),
   '#collapsible' => TRUE,
   '#collapsed' => TRUE,
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
Declarative deïŹnition
                                                    6


'expanded' => array(
   '[name="payment"]' => array('checked' => TRUE)
),



 ➜ Expanded when the element “payment”
   is checked
Dependencies
                                                         7


$form['payment_information'] = array(...
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
                      <fieldset>

           Depends on           InïŹ‚uences


           <input type="checkbox">
Targeting elements
                                                8


◆   Uses plain CSS selectors with jQuery
◆ [name="payment"]
    #edit-payment
    .payment :checkbox, #edit-payment




◆   Don’t use #selector for auto-assigned IDs
States
                                           9


◆   Arbitrary names are possible
◆   visible    irrelevant      confirmed
    checked    valid           important


◆   PreïŹxing with ! negates
◆   visible = !invisible
    invisible = !visible
State aliases
                                                     10


◆   Associate custom aliases              Primary
                                           name
◆   Drupal.states.State.aliases
      ['unimportant'] = '!important';


◆ enabled = !disabled       invisible = !visible
    invalid = !valid        untouched = !touched
    optional = !required    filled = !empty
    unchecked = !checked    irrelevant = !relevant
    expanded = !collapsed   readwrite = !readonly
Drawbacks
                                 11


◆   Doesn’t support OR and XOR
Drawbacks
                                       11


◆   Doesn’t !
         chsupport OR and XOR
      Pat
              drupal.org/node/735528
AND operator
                                        12


'disabled' => array(

     '[name="ccv"]' => array(
       'invalid' => TRUE
     ),


     '[name="card_number"]' => array(
       'invalid' => TRUE
     ),

),
OR operator
                                        13


'disabled' => array(
   array(
     '[name="ccv"]' => array(
        'invalid' => TRUE
      ),
   ),
   array(
     '[name="card_number"]' => array(
        'invalid' => TRUE
      ),
   ),
),
OR operator
                                        13


'disabled' => array(
   array(
     '[name="ccv"]' => array(
        'invalid' => TRUE
      ),
   ),     Numeric keys
   array(
     '[name="card_number"]' => array(
        'invalid' => TRUE
      ),
   ),
),
XOR operator
                                        14


'disabled' => array('xor',
   array(
     '[name="ccv"]' => array(
        'invalid' => TRUE
      ),
   ),
   array(
     '[name="card_number"]' => array(
        'invalid' => TRUE
      ),
   ),
),
XOR operator
                                             14


'disabled' => array('xor',        Operator
   array(
     '[name="ccv"]' => array(
        'invalid' => TRUE
      ),
   ),
   array(
     '[name="card_number"]' => array(
        'invalid' => TRUE
      ),
   ),
),
Drawbacks
                                       15


◆   Doesn’t !
         chsupport OR and XOR
      Pat
              drupal.org/node/735528
Drawbacks
                                       15


◆   Doesn’t !
         chsupport OR and XOR
      Pat
              drupal.org/node/735528

◆   Doesn’t support radio buttons
Drawbacks
                                       15


◆   Doesn’t !
         chsupport OR and XOR
      Pat
              drupal.org/node/735528

◆   Doesn’t support radio buttons
          end!
      E xt
Triggers
Default Triggers
                                       17


Drupal.states.Trigger.states = {
   ...
   checked: {
     'change': function () {
        return this.attr('checked');
      }
   },
   ...
};
Default Triggers
                                       17


Drupal.states.Trigger.states = {
   ...
   checked: {   Native DOM event
     'change': function () {
        return this.attr('checked');
      }
   },
   ...
};
Default Triggers
                                       17


Drupal.states.Trigger.states = {
   ...
   checked: {
     'change': function () {
        return this.attr('checked');
      }
   },
   ...
};
Default Triggers
                                       17


Drupal.states.Trigger.states = {
   ...
   checked: {
     'change': function () {
        return this.attr('checked');
      }
   },
   ...
};           Value function
Default Triggers
                                                                              18


Initialization                         Execution
Drupal.states.Trigger.states = {       Drupal.states.Trigger.states = {
   ...                                    ...
   checked: {                             checked: {
     'change': function () {                'change': function () {
        return this.attr('checked');           return this.attr('checked');
      }                                      }
   },                                     },
   ...                                    ...
};                                     };



$('#element').bind('change',           $('#element').bind('change',
   function() {                           function() {
     ...                                    ...
   }                                      }
);                                     );
Default Triggers
                                                                              18


Initialization                         Execution
Drupal.states.Trigger.states = {       Drupal.states.Trigger.states = {
   ...                                    ...
   checked: {                             checked: {
     'change': function () {                'change': function () {
        return this.attr('checked');           return this.attr('checked');
      }                                      }
   },                                     },
   ...                                    ...
};                                     };



$('#element').bind('change',           $('#element').bind('change',
   function() {                           function() {
     ...                                    ...
   }                                      }
);                                     );
Default Triggers
                                                                              18


Initialization                         Execution
Drupal.states.Trigger.states = {       Drupal.states.Trigger.states = {
   ...                                    ...
   checked: {                             checked: {
     'change': function () {                'change': function () {
        return this.attr('checked');           return this.attr('checked');
      }                                      }
   },                                     },
   ...                                    ...
};                                     };



$('#element').bind('change',           $('#element').bind('change',
   function() {                           function() {
     ...                                    ...
   }                                      }
);                                     );
Multiple Triggers
                                   19


Drupal.states.Trigger.states = {
   ...
   value: {
     'keyup': function () {
        return this.val();
      },
     'change': function () {
        return this.val();
      }
   },
   ...
};
Multiple Triggers
                                     20


Drupal.states.Trigger.states = {
   ...
   value: {
     'keyup change': function () {
        return this.val();
      }
   },
   ...
};
Custom Triggers
                                                     21


'#states' => array(
   'disabled' => array(
     '[name="delayed"]' => array('value' => 'foo')
   ),
),
Custom Triggers
                                                    22


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    var value = element.val(), oldValue, timeout;
    var trigger = function() {
      if (oldValue !== value) {
         element.trigger({
           type: 'state:delayedValue',
           value: value,
           oldValue: oldValue
         });
         oldValue = value;
       }
    };

    ...
  };
Custom Triggers
                                                    22


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    var value = element.val(), oldValue, timeout;
    var trigger = function() {
      if (oldValue !== value) {
         element.trigger({
           type: 'state:delayedValue',
           value: value,
           oldValue: oldValue
         });
         oldValue = value;
       }
    };

    ...
  };
Custom Triggers
                                                    22


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    var value = element.val(), oldValue, timeout;
    var trigger = function() {
      if (oldValue !== value) {
         element.trigger({
           type: 'state:delayedValue',
           value: value,
           oldValue: oldValue
         });
         oldValue = value;
       }
    };

    ...
  };
Custom Triggers
                                                    22


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    var value = element.val(), oldValue, timeout;
    var trigger = function() {
      if (oldValue !== value) {
         element.trigger({
           type: 'state:delayedValue',
           value: value,
           oldValue: oldValue
         });
         oldValue = value;
       }
    };

    ...
  };
Custom Triggers
                                                    22


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    var value = element.val(), oldValue, timeout;
    var trigger = function() {
      if (oldValue !== value) {
         element.trigger({
           type: 'state:delayedValue',
           value: value,
           oldValue: oldValue
         });
         oldValue = value;
       }
    };

    ...
  };
Custom Triggers
                                                     23


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    ...

       element.bind('keyup change', function (e) {
         if (timeout) clearTimeout(timeout);
         timeout = setTimeout(function() {
           value = element.val();
           trigger();
         }, 1000);
       });

       Drupal.states.postponed.push(trigger);
  };
Custom Triggers
                                                     23


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    ...

       element.bind('keyup change', function (e) {
         if (timeout) clearTimeout(timeout);
         timeout = setTimeout(function() {
           value = element.val();
           trigger();
         }, 1000);
       });

       Drupal.states.postponed.push(trigger);
  };
Custom Triggers
                                                     23


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    ...

       element.bind('keyup change', function (e) {
         if (timeout) clearTimeout(timeout);
         timeout = setTimeout(function() {
           value = element.val();
           trigger();
         }, 1000);
       });

       Drupal.states.postponed.push(trigger);
  };
Custom Triggers
                                                     23


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    ...

       element.bind('keyup change', function (e) {
         if (timeout) clearTimeout(timeout);
         timeout = setTimeout(function() {
           value = element.val();
           trigger();
         }, 1000);
       });

       Drupal.states.postponed.push(trigger);
  };
Custom Triggers
                                                     23


Drupal.states.Trigger.states.delayedValue =
  function(element) {
    ...

       element.bind('keyup change', function (e) {
         if (timeout) clearTimeout(timeout);
         timeout = setTimeout(function() {
           value = element.val();
           trigger();
         }, 1000);
       });

       Drupal.states.postponed.push(trigger);
  };
Custom Triggers
                                              24


Drupal.states.Trigger.states.toggle =
  function(element) {
    var value = true, oldValue = undefined;
    var trigger = function() {
       value = !value;
       element.trigger({
         type: 'state:toggle',
         value: value,
         oldValue: oldValue
       });
       oldValue = value;
    };

    setInterval(trigger, 1000);
     Drupal.states.postponed.push(trigger);
  };
Comparisons
Comparisons
                                                         26


$form['payment_information'] = array(
   ...
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),
);
Comparisons
                                                         26


$form['payment_information'] = array(
   ...
   '#states' => array(
     'expanded' => array(
        '[name="payment"]' => array('checked' => TRUE)
      ),
   ),                                      ===
);
Advanced Comparisons
                                               27


states.Dependant.comparisons = {
   'RegExp': function (reference, value) {
     return reference.test(value);
   },
   'Function': function (reference, value) {
     return reference(value);
   }
};
Advanced Comparisons
                                               27


states.Dependant.comparisons = {
   'RegExp': function (reference, value) {
     return reference.test(value);
   },
   'Function': function (reference, value) {
     return reference(value);
   }
};
       Prototype name
JSON only allows
strings and numbers   28
:(   29
Advanced Comparisons
                                                      30


'invalid' => array(
   '[name="card_number"]' => array(
     '!value' => '0000 0000 0000 0000',
   ),
),


'invalid' => array(
   '[name="card_number"]' => array(
     '!value' => array('regex' => '^(d{4}[ -]*){4}$'),
   ),
),
Advanced Comparisons
                                                      30


'invalid' => array(
   '[name="card_number"]' => array(
     '!value' => '0000 0000 0000 0000',
   ),
),


'invalid' => array(
   '[name="card_number"]' => array(
     '!value' => array('regex' => '^(d{4}[ -]*){4}$'),
   ),
),
Advanced Comparisons
                                                       31


Drupal.states.Dependant.comparisons.Object =
  function(reference, value) {
    if ('regex' in reference) {
       return RegExp(reference.regex, ↔
                       reference.flags).test(value);
     }
    else {
       return reference.indexOf(value) !== false;
     }
  };
Advanced Comparisons
                                                      32




'invalid' => array(
   '[name="card_number"]' => array(
     '!value' => array('regex' => '^(d{4}[ -]*){4}$'),
   ),
),
Transitions
State changes
                                               34


◆   Transition an element from one state
    to another

 Direct                  Indirect
◆ Triggered by user     ◆ Triggered by other

◆ Notify listeners        element
                        ◆ Transition element
State changes
                                                  35




$(document).bind('state:checked', function(e) {
  if (e.trigger) {
    $(e.target).attr('checked', e.value);
  }
});
State changes
                                                  35




$(document).bind('state:checked', function(e) {
  if (e.trigger) {
    $(e.target).attr('checked', e.value);
  }
});
State changes
                                                  35




$(document).bind('state:checked', function(e) {
  if (e.trigger) {
    $(e.target).attr('checked', e.value);
  }
});
State changes
                                                  35




$(document).bind('state:checked', function(e) {
  if (e.trigger) {
    $(e.target).attr('checked', e.value);
  }
});
State changes
                                                  35




$(document).bind('state:checked', function(e) {
  if (e.trigger) {
    $(e.target).attr('checked', e.value);
  }
});
document



<html>                  ◆   Event bubbling allows
                            overwriting handlers
<body>                      for speciïŹc regions

<div id="body">         ◆   CSS selectors allow
                            overwriting handlers
<div class="element">       for speciïŹc elements
                                                    36



<input type="text">     State changes
Future Work
Domain-speciïŹc language
                                            38


state_of('[name="baz"]')
  ->is('checked')
    ->when('[name="bar"]')->checked()
      ->and('[name="foo"]')->value('foo')
    ->orWhen('[name="bar"]')->unchecked()

 ->is('disabled')
   ->when('[name="bar"]')->unchecked()

 ->is('invisible')
   ->when('[name="foo"]')->empty();



                      Ideas?
Copy & Paste support   39
Multi-value support
                                                40


// The value of at least one element is true.
{'any': true}

// At least two elements are true.
{'n > 2': true}

// The third element is false.
{'2': false}
Extended values
                                                    41


// The value is greater than 8 or smaller than 5.
[ {'>': 8}, {'<': 5} ]

// At least two elements are between 5 and 8.
{'n > 2': {'>': 5, '<': 8}}

// The sum of the values of all elements is
// greater than 10.
{'sum': {'>=': 10}}
Questions?
                              42




kkaefer.com/2010/states.pdf
    mail@kkaefer.com

Weitere Àhnliche Inhalte

Ähnlich wie Instant Dynamic Forms with #states

Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
Introduction Ă  CoffeeScript pour ParisRB
Introduction Ă  CoffeeScript pour ParisRB Introduction Ă  CoffeeScript pour ParisRB
Introduction Ă  CoffeeScript pour ParisRB jhchabran
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegamehozayfa999
 
[PHPCon 2023] “Kto to pisaƂ?!... a, to ja.”, czyli sposoby ĆŒeby znienawidzić ...
[PHPCon 2023] “Kto to pisaƂ?!... a, to ja.”, czyli sposoby ĆŒeby znienawidzić ...[PHPCon 2023] “Kto to pisaƂ?!... a, to ja.”, czyli sposoby ĆŒeby znienawidzić ...
[PHPCon 2023] “Kto to pisaƂ?!... a, to ja.”, czyli sposoby ĆŒeby znienawidzić ...Mateusz Zalewski
 
PHP record- with all programs and output
PHP record- with all programs and outputPHP record- with all programs and output
PHP record- with all programs and outputKavithaK23
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsDavid Golden
 
The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of TransductionDavid Stockton
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubyJason Yeo Jie Shun
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuerysergioafp
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersKacper Gunia
 
Arrays in php
Arrays in phpArrays in php
Arrays in phpLaiby Thomas
 
Desarrollo de mĂłdulos en Drupal e integraciĂłn con dispositivos mĂłviles
Desarrollo de mĂłdulos en Drupal e integraciĂłn con dispositivos mĂłvilesDesarrollo de mĂłdulos en Drupal e integraciĂłn con dispositivos mĂłviles
Desarrollo de mĂłdulos en Drupal e integraciĂłn con dispositivos mĂłvilesLuis Curo Salvatierra
 
Fields in Core: How to create a custom field
Fields in Core: How to create a custom fieldFields in Core: How to create a custom field
Fields in Core: How to create a custom fieldIvan Zugec
 
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012Amazon Web Services
 
Refactoring group 1 - chapter 3,4,6
Refactoring   group 1 - chapter 3,4,6Refactoring   group 1 - chapter 3,4,6
Refactoring group 1 - chapter 3,4,6Duy LĂąm
 

Ähnlich wie Instant Dynamic Forms with #states (20)

Php functions
Php functionsPhp functions
Php functions
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
Php & my sql
Php & my sqlPhp & my sql
Php & my sql
 
Introduction Ă  CoffeeScript pour ParisRB
Introduction Ă  CoffeeScript pour ParisRB Introduction Ă  CoffeeScript pour ParisRB
Introduction Ă  CoffeeScript pour ParisRB
 
Gta v savegame
Gta v savegameGta v savegame
Gta v savegame
 
[PHPCon 2023] “Kto to pisaƂ?!... a, to ja.”, czyli sposoby ĆŒeby znienawidzić ...
[PHPCon 2023] “Kto to pisaƂ?!... a, to ja.”, czyli sposoby ĆŒeby znienawidzić ...[PHPCon 2023] “Kto to pisaƂ?!... a, to ja.”, czyli sposoby ĆŒeby znienawidzić ...
[PHPCon 2023] “Kto to pisaƂ?!... a, to ja.”, czyli sposoby ĆŒeby znienawidzić ...
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
 
PHP record- with all programs and output
PHP record- with all programs and outputPHP record- with all programs and output
PHP record- with all programs and output
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
The Art of Transduction
The Art of TransductionThe Art of Transduction
The Art of Transduction
 
Slaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in RubySlaying the Dragon: Implementing a Programming Language in Ruby
Slaying the Dragon: Implementing a Programming Language in Ruby
 
Presentation1
Presentation1Presentation1
Presentation1
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
Arrays in php
Arrays in phpArrays in php
Arrays in php
 
Desarrollo de mĂłdulos en Drupal e integraciĂłn con dispositivos mĂłviles
Desarrollo de mĂłdulos en Drupal e integraciĂłn con dispositivos mĂłvilesDesarrollo de mĂłdulos en Drupal e integraciĂłn con dispositivos mĂłviles
Desarrollo de mĂłdulos en Drupal e integraciĂłn con dispositivos mĂłviles
 
Fields in Core: How to create a custom field
Fields in Core: How to create a custom fieldFields in Core: How to create a custom field
Fields in Core: How to create a custom field
 
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
TLS305 Using DynamoDB with the AWS SDK for PHP - AWS re: Invent 2012
 
Refactoring group 1 - chapter 3,4,6
Refactoring   group 1 - chapter 3,4,6Refactoring   group 1 - chapter 3,4,6
Refactoring group 1 - chapter 3,4,6
 

Mehr von Konstantin KĂ€fer

Mehr von Konstantin KĂ€fer (6)

Front End Performance
Front End PerformanceFront End Performance
Front End Performance
 
Front End Performance
Front End PerformanceFront End Performance
Front End Performance
 
Developing JavaScript Widgets
Developing JavaScript WidgetsDeveloping JavaScript Widgets
Developing JavaScript Widgets
 
Front End Performance
Front End PerformanceFront End Performance
Front End Performance
 
Typography on the Web
Typography on the WebTypography on the Web
Typography on the Web
 
What's New in Web Development
What's New in Web DevelopmentWhat's New in Web Development
What's New in Web Development
 

KĂŒrzlich hochgeladen

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...gurkirankumar98700
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 

KĂŒrzlich hochgeladen (20)

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍾 8923113531 🎰 Avail...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

Instant Dynamic Forms with #states

  • 1. Instant Dynamic Forms with #states
  • 4. 4
  • 5. Anatomy of a state 5 $form['payment_information'] = array( '#type' => 'fieldset', '#title' => t('Payment information'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), );
  • 6. Anatomy of a state 5 $form['payment_information'] = array( '#type' => 'fieldset', '#title' => t('Payment information'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), );
  • 7. Anatomy of a state 5 $form['payment_information'] = array( '#type' => 'fieldset', '#title' => t('Payment information'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), );
  • 8. Anatomy of a state 5 $form['payment_information'] = array( '#type' => 'fieldset', '#title' => t('Payment information'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), );
  • 9. Anatomy of a state 5 $form['payment_information'] = array( '#type' => 'fieldset', '#title' => t('Payment information'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), );
  • 10. Anatomy of a state 5 $form['payment_information'] = array( '#type' => 'fieldset', '#title' => t('Payment information'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), );
  • 11. Anatomy of a state 5 $form['payment_information'] = array( '#type' => 'fieldset', '#title' => t('Payment information'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), );
  • 12. Anatomy of a state 5 $form['payment_information'] = array( '#type' => 'fieldset', '#title' => t('Payment information'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), );
  • 13. Declarative deïŹnition 6 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ➜ Expanded when the element “payment” is checked
  • 14. Dependencies 7 $form['payment_information'] = array(... '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), ); <fieldset> Depends on InïŹ‚uences <input type="checkbox">
  • 15. Targeting elements 8 ◆ Uses plain CSS selectors with jQuery ◆ [name="payment"] #edit-payment .payment :checkbox, #edit-payment ◆ Don’t use #selector for auto-assigned IDs
  • 16. States 9 ◆ Arbitrary names are possible ◆ visible irrelevant confirmed checked valid important ◆ PreïŹxing with ! negates ◆ visible = !invisible invisible = !visible
  • 17. State aliases 10 ◆ Associate custom aliases Primary name ◆ Drupal.states.State.aliases ['unimportant'] = '!important'; ◆ enabled = !disabled invisible = !visible invalid = !valid untouched = !touched optional = !required filled = !empty unchecked = !checked irrelevant = !relevant expanded = !collapsed readwrite = !readonly
  • 18. Drawbacks 11 ◆ Doesn’t support OR and XOR
  • 19. Drawbacks 11 ◆ Doesn’t ! chsupport OR and XOR Pat drupal.org/node/735528
  • 20. AND operator 12 'disabled' => array( '[name="ccv"]' => array( 'invalid' => TRUE ), '[name="card_number"]' => array( 'invalid' => TRUE ), ),
  • 21. OR operator 13 'disabled' => array( array( '[name="ccv"]' => array( 'invalid' => TRUE ), ), array( '[name="card_number"]' => array( 'invalid' => TRUE ), ), ),
  • 22. OR operator 13 'disabled' => array( array( '[name="ccv"]' => array( 'invalid' => TRUE ), ), Numeric keys array( '[name="card_number"]' => array( 'invalid' => TRUE ), ), ),
  • 23. XOR operator 14 'disabled' => array('xor', array( '[name="ccv"]' => array( 'invalid' => TRUE ), ), array( '[name="card_number"]' => array( 'invalid' => TRUE ), ), ),
  • 24. XOR operator 14 'disabled' => array('xor', Operator array( '[name="ccv"]' => array( 'invalid' => TRUE ), ), array( '[name="card_number"]' => array( 'invalid' => TRUE ), ), ),
  • 25. Drawbacks 15 ◆ Doesn’t ! chsupport OR and XOR Pat drupal.org/node/735528
  • 26. Drawbacks 15 ◆ Doesn’t ! chsupport OR and XOR Pat drupal.org/node/735528 ◆ Doesn’t support radio buttons
  • 27. Drawbacks 15 ◆ Doesn’t ! chsupport OR and XOR Pat drupal.org/node/735528 ◆ Doesn’t support radio buttons end! E xt
  • 29. Default Triggers 17 Drupal.states.Trigger.states = { ... checked: { 'change': function () { return this.attr('checked'); } }, ... };
  • 30. Default Triggers 17 Drupal.states.Trigger.states = { ... checked: { Native DOM event 'change': function () { return this.attr('checked'); } }, ... };
  • 31. Default Triggers 17 Drupal.states.Trigger.states = { ... checked: { 'change': function () { return this.attr('checked'); } }, ... };
  • 32. Default Triggers 17 Drupal.states.Trigger.states = { ... checked: { 'change': function () { return this.attr('checked'); } }, ... }; Value function
  • 33. Default Triggers 18 Initialization Execution Drupal.states.Trigger.states = { Drupal.states.Trigger.states = { ... ... checked: { checked: { 'change': function () { 'change': function () { return this.attr('checked'); return this.attr('checked'); } } }, }, ... ... }; }; $('#element').bind('change', $('#element').bind('change', function() { function() { ... ... } } ); );
  • 34. Default Triggers 18 Initialization Execution Drupal.states.Trigger.states = { Drupal.states.Trigger.states = { ... ... checked: { checked: { 'change': function () { 'change': function () { return this.attr('checked'); return this.attr('checked'); } } }, }, ... ... }; }; $('#element').bind('change', $('#element').bind('change', function() { function() { ... ... } } ); );
  • 35. Default Triggers 18 Initialization Execution Drupal.states.Trigger.states = { Drupal.states.Trigger.states = { ... ... checked: { checked: { 'change': function () { 'change': function () { return this.attr('checked'); return this.attr('checked'); } } }, }, ... ... }; }; $('#element').bind('change', $('#element').bind('change', function() { function() { ... ... } } ); );
  • 36. Multiple Triggers 19 Drupal.states.Trigger.states = { ... value: { 'keyup': function () { return this.val(); }, 'change': function () { return this.val(); } }, ... };
  • 37. Multiple Triggers 20 Drupal.states.Trigger.states = { ... value: { 'keyup change': function () { return this.val(); } }, ... };
  • 38. Custom Triggers 21 '#states' => array( 'disabled' => array( '[name="delayed"]' => array('value' => 'foo') ), ),
  • 39. Custom Triggers 22 Drupal.states.Trigger.states.delayedValue = function(element) { var value = element.val(), oldValue, timeout; var trigger = function() { if (oldValue !== value) { element.trigger({ type: 'state:delayedValue', value: value, oldValue: oldValue }); oldValue = value; } }; ... };
  • 40. Custom Triggers 22 Drupal.states.Trigger.states.delayedValue = function(element) { var value = element.val(), oldValue, timeout; var trigger = function() { if (oldValue !== value) { element.trigger({ type: 'state:delayedValue', value: value, oldValue: oldValue }); oldValue = value; } }; ... };
  • 41. Custom Triggers 22 Drupal.states.Trigger.states.delayedValue = function(element) { var value = element.val(), oldValue, timeout; var trigger = function() { if (oldValue !== value) { element.trigger({ type: 'state:delayedValue', value: value, oldValue: oldValue }); oldValue = value; } }; ... };
  • 42. Custom Triggers 22 Drupal.states.Trigger.states.delayedValue = function(element) { var value = element.val(), oldValue, timeout; var trigger = function() { if (oldValue !== value) { element.trigger({ type: 'state:delayedValue', value: value, oldValue: oldValue }); oldValue = value; } }; ... };
  • 43. Custom Triggers 22 Drupal.states.Trigger.states.delayedValue = function(element) { var value = element.val(), oldValue, timeout; var trigger = function() { if (oldValue !== value) { element.trigger({ type: 'state:delayedValue', value: value, oldValue: oldValue }); oldValue = value; } }; ... };
  • 44. Custom Triggers 23 Drupal.states.Trigger.states.delayedValue = function(element) { ... element.bind('keyup change', function (e) { if (timeout) clearTimeout(timeout); timeout = setTimeout(function() { value = element.val(); trigger(); }, 1000); }); Drupal.states.postponed.push(trigger); };
  • 45. Custom Triggers 23 Drupal.states.Trigger.states.delayedValue = function(element) { ... element.bind('keyup change', function (e) { if (timeout) clearTimeout(timeout); timeout = setTimeout(function() { value = element.val(); trigger(); }, 1000); }); Drupal.states.postponed.push(trigger); };
  • 46. Custom Triggers 23 Drupal.states.Trigger.states.delayedValue = function(element) { ... element.bind('keyup change', function (e) { if (timeout) clearTimeout(timeout); timeout = setTimeout(function() { value = element.val(); trigger(); }, 1000); }); Drupal.states.postponed.push(trigger); };
  • 47. Custom Triggers 23 Drupal.states.Trigger.states.delayedValue = function(element) { ... element.bind('keyup change', function (e) { if (timeout) clearTimeout(timeout); timeout = setTimeout(function() { value = element.val(); trigger(); }, 1000); }); Drupal.states.postponed.push(trigger); };
  • 48. Custom Triggers 23 Drupal.states.Trigger.states.delayedValue = function(element) { ... element.bind('keyup change', function (e) { if (timeout) clearTimeout(timeout); timeout = setTimeout(function() { value = element.val(); trigger(); }, 1000); }); Drupal.states.postponed.push(trigger); };
  • 49. Custom Triggers 24 Drupal.states.Trigger.states.toggle = function(element) { var value = true, oldValue = undefined; var trigger = function() { value = !value; element.trigger({ type: 'state:toggle', value: value, oldValue: oldValue }); oldValue = value; }; setInterval(trigger, 1000); Drupal.states.postponed.push(trigger); };
  • 51. Comparisons 26 $form['payment_information'] = array( ... '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), );
  • 52. Comparisons 26 $form['payment_information'] = array( ... '#states' => array( 'expanded' => array( '[name="payment"]' => array('checked' => TRUE) ), ), === );
  • 53. Advanced Comparisons 27 states.Dependant.comparisons = { 'RegExp': function (reference, value) { return reference.test(value); }, 'Function': function (reference, value) { return reference(value); } };
  • 54. Advanced Comparisons 27 states.Dependant.comparisons = { 'RegExp': function (reference, value) { return reference.test(value); }, 'Function': function (reference, value) { return reference(value); } }; Prototype name
  • 55. JSON only allows strings and numbers 28
  • 56. :( 29
  • 57. Advanced Comparisons 30 'invalid' => array( '[name="card_number"]' => array( '!value' => '0000 0000 0000 0000', ), ), 'invalid' => array( '[name="card_number"]' => array( '!value' => array('regex' => '^(d{4}[ -]*){4}$'), ), ),
  • 58. Advanced Comparisons 30 'invalid' => array( '[name="card_number"]' => array( '!value' => '0000 0000 0000 0000', ), ), 'invalid' => array( '[name="card_number"]' => array( '!value' => array('regex' => '^(d{4}[ -]*){4}$'), ), ),
  • 59. Advanced Comparisons 31 Drupal.states.Dependant.comparisons.Object = function(reference, value) { if ('regex' in reference) { return RegExp(reference.regex, ↔ reference.flags).test(value); } else { return reference.indexOf(value) !== false; } };
  • 60. Advanced Comparisons 32 'invalid' => array( '[name="card_number"]' => array( '!value' => array('regex' => '^(d{4}[ -]*){4}$'), ), ),
  • 62. State changes 34 ◆ Transition an element from one state to another Direct Indirect ◆ Triggered by user ◆ Triggered by other ◆ Notify listeners element ◆ Transition element
  • 63. State changes 35 $(document).bind('state:checked', function(e) { if (e.trigger) { $(e.target).attr('checked', e.value); } });
  • 64. State changes 35 $(document).bind('state:checked', function(e) { if (e.trigger) { $(e.target).attr('checked', e.value); } });
  • 65. State changes 35 $(document).bind('state:checked', function(e) { if (e.trigger) { $(e.target).attr('checked', e.value); } });
  • 66. State changes 35 $(document).bind('state:checked', function(e) { if (e.trigger) { $(e.target).attr('checked', e.value); } });
  • 67. State changes 35 $(document).bind('state:checked', function(e) { if (e.trigger) { $(e.target).attr('checked', e.value); } });
  • 68. document <html> ◆ Event bubbling allows overwriting handlers <body> for speciïŹc regions <div id="body"> ◆ CSS selectors allow overwriting handlers <div class="element"> for speciïŹc elements 36 <input type="text"> State changes
  • 70. Domain-speciïŹc language 38 state_of('[name="baz"]') ->is('checked') ->when('[name="bar"]')->checked() ->and('[name="foo"]')->value('foo') ->orWhen('[name="bar"]')->unchecked() ->is('disabled') ->when('[name="bar"]')->unchecked() ->is('invisible') ->when('[name="foo"]')->empty(); Ideas?
  • 71. Copy & Paste support 39
  • 72. Multi-value support 40 // The value of at least one element is true. {'any': true} // At least two elements are true. {'n > 2': true} // The third element is false. {'2': false}
  • 73. Extended values 41 // The value is greater than 8 or smaller than 5. [ {'>': 8}, {'<': 5} ] // At least two elements are between 5 and 8. {'n > 2': {'>': 5, '<': 8}} // The sum of the values of all elements is // greater than 10. {'sum': {'>=': 10}}
  • 74. Questions? 42 kkaefer.com/2010/states.pdf mail@kkaefer.com