Last active
October 27, 2016 00:00
-
-
Save jdavidbakr/4662ae1ea7b0b7725485 to your computer and use it in GitHub Desktop.
Laravel: AjaxFormBuilder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Services; | |
use Collective\Html\FormBuilder; | |
class AjaxFormBuilder extends FormBuilder { | |
protected $form_id; | |
protected $readonly = false; | |
public function readonly($value=true) | |
{ | |
$this->readonly = $value; | |
} | |
public function input($type, $name, $value = null, $options = []) | |
{ | |
if($this->readonly) { | |
$options['disabled'] = true; | |
} | |
return parent::input($type, $name, $value, $options); | |
} | |
public function textarea($name, $value = null, $options = []) | |
{ | |
if($this->readonly) { | |
$options['disabled'] = true; | |
} | |
return parent::textarea($name, $value, $options); | |
} | |
public function countdown_textarea($name, $value = null, $options = []) | |
{ | |
if($this->readonly) { | |
$html = $this->textarea($name, $value, $options); | |
} else { | |
$id = 'count-'.str_random(5); | |
$options['onkeyup'] = 'TextCountdown.Update(this, "'.$id.'");'; | |
$html = $this->textarea($name, $value, $options); | |
$html .= '<div class="countdown_text">Remaining characters: <span id="'.$id.'">'.$options['maxlength'].'</span></div>'; | |
} | |
return $html; | |
} | |
public function select($name, $list = [], $selected = null, $options = []) | |
{ | |
if($this->readonly) { | |
$options['disabled'] = true; | |
} | |
return parent::select($name, $list, $selected, $options); | |
} | |
/** | |
* Opens a new form, attaching the onsubmit attribute | |
* @param array $options | |
* @return string | |
*/ | |
public function open(array $options = array()) { | |
if (!empty($options['id'])) { | |
$this->form_id = $options['id']; | |
} else { | |
$this->form_id = str_random(10); | |
$options['id'] = $this->form_id; | |
} | |
if(empty($options['no-warning'])) { | |
$options['onchange'] = 'PageChangeWarning.change_made();'; | |
} | |
$options['onsubmit'] = 'AjaxForm.submit(this);return false;'; | |
return parent::open($options); | |
} | |
/** | |
* Creates a submit button with the "button" class, as well as a hidden submit button so the form submits on enter | |
* @param string $value | |
* @param array $attributes | |
* @return string | |
*/ | |
public function submit($value = null, $attributes = array()) { | |
if($this->readonly) { | |
// No submit button on a read-only form | |
return; | |
} | |
if (!empty($attributes['class'])) { | |
$classes = explode(" ", $attributes['class']); | |
} else { | |
$classes = array(); | |
} | |
$classes[] = 'button'; | |
$attributes['class'] = implode(" ", $classes); | |
$attributes['onclick'] = "AjaxForm.submit_button_click('{$this->form_id}')"; | |
$attributes = $this->html->attributes($attributes); | |
return '<input type="submit" class="hidden" id="submitbtn" name="Submit" /><a' . $attributes . '>' . htmlspecialchars(!empty($value) ? $value : 'Submit') . '</a>'; | |
} | |
/** | |
* Hidden Subform select | |
* @param string $name | |
* @param array $list List of options | |
* @param array $option_attributes List of attributes for the option elements - keyed with their keys | |
* @param bool $selected | |
* @param array $options The select element's attributes | |
* @return string | |
*/ | |
public function hs_select($name, $list = array(), $option_attributes = array(), $selected = null, $options = array()) { | |
// When building a select box the "value" attribute is really the selected one | |
// so we will use that when checking the model or session for a value which | |
// should provide a convenient method of re-populating the forms on post. | |
$selected = $this->getValueAttribute($name, $selected); | |
if($this->readonly) { | |
$options['disabled'] = true; | |
} | |
$options['id'] = $this->getIdAttribute($name, $options); | |
if (!isset($options['name'])) { | |
$options['name'] = $name; | |
} | |
$options['onchange'] = 'HiddenSubform.update(this)'; | |
// We will simply loop through the options and build an HTML value for each of | |
// them until we have an array of HTML declarations. Then we will join them | |
// all together into one single HTML element that can be put on the form. | |
$html = array(); | |
$id = str_random(10); | |
$options['id'] = $id; | |
foreach ($list as $value => $display) { | |
$html[] = $this->hs_getSelectOption($display, | |
$option_attributes, | |
$value, | |
$selected); | |
} | |
// Once we have all of this HTML, we can join this into a single element after | |
// formatting the attributes into an HTML "attributes" string, then we will | |
// build out a final select statement, which will contain all the values. | |
$options = $this->html->attributes($options); | |
$list = implode('', $html); | |
$select = "<select{$options}>{$list}</select>"; | |
$script = "<script>document.addEventListener('DOMContentLoaded', function(event) { document.getElementById('{$id}').onchange() })</script>"; | |
return $select . $script; | |
} | |
public function hs_getSelectOption($display, $option_attributes, $value, $selected) | |
{ | |
if(is_array($display)) { | |
return $this->hs_optionGroup($display, $option_attributes, $value, $selected); | |
} | |
return $this->hs_option($display, $option_attributes, $value, $selected); | |
} | |
public function hs_optionGroup($list, $option_attributes, $label, $selected) | |
{ | |
$html = []; | |
foreach($list as $value => $display) | |
{ | |
$html[] = $this->hs_option($display, $option_attributes, $value, $selected); | |
} | |
return '<optgroup label="' . e($label) . '">' . implode('', $html) . '</optgroup>'; | |
} | |
public function hs_option($display, $option_attributes, $value, $selected) | |
{ | |
$sel = $this->getSelectedValue($value, $selected); | |
$option_options = [ | |
'value' => e($value), | |
'selected' => $sel | |
]; | |
if(!empty($option_attributes[$value])) { | |
$option_options = array_merge($option_options, $option_attributes[$value]); | |
} | |
return '<option' . $this->html->attributes($option_options) . '>' . e($display) . '</option>'; | |
} | |
public function hs_checkbox($name, $value = 1, $checked = null, $options = []) | |
{ | |
$id = str_random(10); | |
$options['id'] = $id; | |
$options['onchange'] = 'HiddenSubform.update(this)'; | |
$checkbox = $this->checkable('checkbox', $name, $value, $checked, $options); | |
$script = "<script>document.addEventListener('DOMContentLoaded', function(event) { document.getElementById('{$id}').onchange() })</script>"; | |
return $checkbox . $script; | |
} | |
/** | |
* Creates a calendar object that manages the popup calendar | |
* @param string $name | |
* @param string $default | |
* @param array $options Additional attributes for the input element (not the visible one) | |
* @return string | |
*/ | |
public function calendar($name, $default = null, $options = array()) | |
{ | |
if ( ! isset($options['name'])) $options['name'] = $name; | |
$options['type'] = 'text'; | |
$options['style'] = 'display: none;'; | |
// We will get the appropriate value for the given field. We will look for the | |
// value in the session for the value in the old input data then we'll look | |
// in the model instance if one is set. Otherwise we will just use empty. | |
$id = $this->getIdAttribute($name, $options); | |
$value = $this->getValueAttribute($name, $default); | |
// Once we have the type, value, and ID we can merge them into the rest of the | |
// attributes array so we can convert them into their HTML attribute format | |
// when creating the HTML element. Then, we will return the entire input. | |
$merge = compact('type', 'value', 'id'); | |
$options = array_merge($options, $merge); | |
// Create the picker options | |
$picker_options = array(); | |
$picker_options['onclick'] = 'return datepicker.activate(event, this)'; | |
$picker_options['onfocus'] = 'this.blur(); return datepicker.activate(event, this)'; | |
$picker_options['rel'] = $id; | |
if($value) { | |
$picker_options['value'] = date("n/d/Y", strtotime($value)); | |
} | |
return '<input'.$this->html->attributes($options).'><input'.$this->html->attributes($picker_options).'>'; | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment