├── AjaxSubmitButton.php ├── README.md ├── README.ru.md └── composer.json /AjaxSubmitButton.php: -------------------------------------------------------------------------------- 1 | 18 | * 'country_code', 20 | * 'data' => Country::getAllCountries(), 21 | * 'options' => [ 22 | * 'id' => 'country_select', 23 | * 'multiple' => false, 24 | * 'placeholder' => 'Select country...', 25 | * 'class' => 'uk-width-medium-7-10' 26 | * ] 27 | * ]);?> 28 | * 29 | * 'Проверить', 31 | * 'ajaxOptions'=> 32 | * [ 33 | * 'type'=>'POST', 34 | * 'url'=>'country/getinfo', 35 | * 'cache' => false, 36 | * 'success' => new \yii\web\JsExpression('function(html){ 37 | * $("#output").html(html); 38 | * }'), 39 | * ], 40 | * 'options' => ['type' => 'submit'], 41 | * ]); 42 | * AjaxSubmitButton::end();?> 43 | * 44 | * 45 | * ``` 46 | * 47 | * @author Oleg Martemjanov 48 | */ 49 | class AjaxSubmitButton extends Widget 50 | { 51 | 52 | /** 53 | * Icon positions 54 | */ 55 | const ICON_POSITION_LEFT = 'left'; 56 | 57 | const ICON_POSITION_RIGHT = 'right'; 58 | 59 | public $ajaxOptions = []; 60 | 61 | /** 62 | * @var array the HTML attributes for the widget container tag. 63 | */ 64 | public $options = []; 65 | 66 | /** 67 | * @var string the tag to use to render the button 68 | */ 69 | public $tagName = 'button'; 70 | 71 | /** 72 | * @var string the button label 73 | */ 74 | public $label = 'Button'; 75 | 76 | /** 77 | * @var string The button icon. 78 | */ 79 | public $icon; 80 | 81 | /** 82 | * @var string Icon position. 83 | * Valid values are 'left', 'right'. 84 | */ 85 | public $iconPosition = self::ICON_POSITION_LEFT; 86 | 87 | /** 88 | * @var boolean whether the label should be HTML-encoded. 89 | */ 90 | public $encodeLabel = true; 91 | 92 | /** 93 | * @var string js object name. 94 | * it is unused when useWithActiveForm is enabled 95 | */ 96 | public $clickedButtonVarName = '_clickedButton'; 97 | 98 | /** 99 | * @var boolean whether the button should not be used with ActiveForm. 100 | * string the id of ActiveForm to use the button with 101 | */ 102 | public $useWithActiveForm = false; 103 | 104 | 105 | /** 106 | * Initializes the widget. 107 | */ 108 | public function init() 109 | { 110 | parent::init(); 111 | 112 | if (!isset($this->options['id'])) { 113 | $this->options['id'] = $this->getId(); 114 | } 115 | } 116 | 117 | public function run() 118 | { 119 | parent::run(); 120 | 121 | $label = $this->encodeLabel ? Html::encode($this->label) : $this->label; 122 | 123 | if ($this->icon !== null) { 124 | $icon = Html::tag('i', '', ['class' => $this->icon]); 125 | $label = strcasecmp($this->iconPosition, 126 | self::ICON_POSITION_LEFT) === 0 ? sprintf('%s %s', $icon, 127 | $label) : sprintf('%s %s', $label, $icon); 128 | } 129 | 130 | echo Html::tag($this->tagName, 131 | $label, 132 | $this->options); 133 | 134 | if (!empty($this->ajaxOptions)) { 135 | 136 | if ($this->useWithActiveForm !== false) { 137 | $this->registerAjaxFormScript(); 138 | } else { 139 | $this->registerAjaxScript(); 140 | } 141 | } 142 | } 143 | 144 | protected function registerAjaxFormScript() 145 | { 146 | $view = $this->getView(); 147 | 148 | if (!isset($this->ajaxOptions['type'])) { 149 | $this->ajaxOptions['type'] = new JsExpression('$(this).attr("method")'); 150 | } 151 | 152 | if (!isset($this->ajaxOptions['url'])) { 153 | $this->ajaxOptions['url'] = new JsExpression('$(this).attr("action")'); 154 | } 155 | 156 | if (!isset($this->ajaxOptions['data']) && isset($this->ajaxOptions['type'])) { 157 | $this->ajaxOptions['data'] = new JsExpression('$(this).serialize()'); 158 | } 159 | 160 | $this->ajaxOptions = Json::encode($this->ajaxOptions); 161 | 162 | $js = <<useWithActiveForm}').on('beforeSubmit.{$this->useWithActiveForm}', "#{$this->useWithActiveForm}", function () { 164 | if ($(this).find('.has-error').length < 1) { 165 | $.ajax({$this->ajaxOptions}); 166 | } 167 | return false; // Cancel form submitting. 168 | }); 169 | SEL; 170 | 171 | $view->registerJs($js); 172 | 173 | 174 | } 175 | 176 | protected function registerAjaxScript() 177 | { 178 | $view = $this->getView(); 179 | 180 | if (!isset($this->ajaxOptions['type'])) { 181 | $this->ajaxOptions['type'] = new JsExpression('$(this).parents("form").attr("method")'); 182 | } 183 | 184 | if (!isset($this->ajaxOptions['url'])) { 185 | $this->ajaxOptions['url'] = new JsExpression('$(this).parents("form").attr("action")'); 186 | } 187 | 188 | if (!isset($this->ajaxOptions['data']) && isset($this->ajaxOptions['type'])) { 189 | $this->ajaxOptions['data'] = new JsExpression('$(this).parents("form").serialize()'); 190 | } 191 | 192 | $this->ajaxOptions = Json::encode($this->ajaxOptions); 193 | $view->registerJs("$('#" . $this->options['id'] . "').unbind('click').click(function() { 194 | " . (null !== $this->clickedButtonVarName ? "var {$this->clickedButtonVarName} = this;" : "") . " 195 | $.ajax(" . $this->ajaxOptions . "); 196 | return false; 197 | });"); 198 | } 199 | 200 | } 201 | 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AjaxSubmitButton for Yii 2 2 | ===================================== 3 | 4 | [![Latest Stable Version](https://poser.pugx.org/demogorgorn/yii2-ajax-submit-button/v/stable)](https://packagist.org/packages/demogorgorn/yii2-ajax-submit-button) 5 | [![Total Downloads](https://poser.pugx.org/demogorgorn/yii2-ajax-submit-button/downloads)](https://packagist.org/packages/demogorgorn/yii2-ajax-submit-button) 6 | [![License](https://poser.pugx.org/demogorgorn/yii2-ajax-submit-button/license)](https://packagist.org/packages/demogorgorn/yii2-ajax-submit-button) 7 | [![Monthly Downloads](https://poser.pugx.org/demogorgorn/yii2-ajax-submit-button/d/monthly)](https://packagist.org/packages/demogorgorn/yii2-ajax-submit-button) 8 | [![Yii2](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](http://www.yiiframework.com/) 9 | 10 | 11 | This is the powerful AjaxSubmitButton widget that renders an ajax button which is very similar to ajaxSubmitButton from Yii1 for Yii 2, but has many useful functions. 12 | 13 | ### Basic Example 14 | 15 | Example of usage of the widget with a custom widget (in this case Select2 widget). 16 | 17 | The view: 18 | ```php 19 | use demogorgorn\ajax\AjaxSubmitButton; 20 | 21 | 'uk-width-medium-1-1 uk-form uk-form-horizontal']); ?> 22 | 23 | 'country_code', 25 | 'data' => Country::getAllCountries(), 26 | 'options' => [ 27 | 'id' => 'country_select', 28 | 'multiple' => false, 29 | 'placeholder' => 'Choose...', 30 | 'class' => 'uk-width-medium-7-10'] 31 | ]); 32 | ?> 33 | 34 | 'Check', 36 | 'ajaxOptions' => [ 37 | 'type'=>'POST', 38 | 'url'=>'country/getinfo', 39 | 'success' => new \yii\web\JsExpression('function(html){ 40 | $("#output").html(html); 41 | }'), 42 | ], 43 | 'options' => ['class' => 'customclass', 'type' => 'submit'], 44 | ]); 45 | AjaxSubmitButton::end(); 46 | ?> 47 | 48 | 49 | 50 |
51 | ``` 52 | 53 | > Please note: that #output is a div element which will be updated. 54 | 55 | In controller: 56 | ```php 57 | public function actionGetinfo() 58 | { 59 | if(!isset($_POST['country_code']) || empty($_POST['country_code'])) 60 | return; 61 | 62 | $code = $_POST['country_code']; 63 | 64 | return $this->renderAjax('resultwidget', ['code' => $code]); 65 | } 66 | ``` 67 | 68 | ### Example of usage with ActiveForm and client validation 69 | 70 | The view: 71 | ```php 72 | $form = ActiveForm::begin([ 73 | 'id' => 'add-form', 74 | 'options' => ['class' => 'form-inline'], 75 | ]); 76 | 77 | ... 78 | 79 | AjaxSubmitButton::begin([ 80 | 'label' => 'Add', 81 | 'useWithActiveForm' => 'add-form', 82 | 'ajaxOptions' => [ 83 | 'type' => 'POST', 84 | 'success' => new \yii\web\JsExpression("function(data) { 85 | if (data.status == true) 86 | { 87 | closeTopbar(); 88 | } 89 | }"), 90 | ], 91 | 'options' => ['class' => 'btn btn-primary', 'type' => 'submit', 'id' =>'add-button'], 92 | ]); 93 | AjaxSubmitButton::end(); 94 | 95 | ActiveForm::end() 96 | ``` 97 | 98 | > As you can see it's quite easy to use the widget with ActiveForm - enough to set the ActiveForm's id to the 'useWithActiveForm' variable. (In this case id is 'add-form', without '#' symbol!). 99 | 100 | 101 | ### Client validation 102 | 103 | As I said before the widget can be used with ActiveForm and client validation enabled. If you wish to disable it, just set ActiveForm's 'enableClientValidation' to false. 104 | 105 | ```php 106 | $form = ActiveForm::begin([ 107 | 'id' => 'filters-form', 108 | 'enableClientValidation' => false 109 | ]); 110 | ``` 111 | 112 | ### Preloader use 113 | 114 | It's possible to use the widget with your own custom preloader. 115 | 116 | ```php 117 | 'Check', 119 | 'ajaxOptions' => [ 120 | 'type'=>'POST', 121 | 'url'=>'country/getinfo', 122 | 'beforeSend' => new \yii\web\JsExpression('function(html){ 123 | ... show preloader... 124 | }'), 125 | 'success' => new \yii\web\JsExpression('function(html){ 126 | ... hide preloader ... 127 | }'), 128 | ], 129 | 'options' => ['class' => 'customclass', 'type' => 'submit'], 130 | ]); 131 | AjaxSubmitButton::end(); 132 | ?> 133 | ``` 134 | 135 | ### File Uploads 136 | 137 | AjaxSubmitButton fully supports file uploads. 138 | For example (look at the comments): 139 | 140 | ```php 141 | 'Сохранить', 143 | 'useWithActiveForm' => 'add-form', 144 | 'ajaxOptions' => [ 145 | 'type' => 'POST', 146 | 'processData' => false, // Don't process the files 147 | 'contentType' => false, // Set content type to false as jQuery will tell the server its a query string request 148 | 'data' => new \yii\web\JsExpression("new FormData($('#add-form')[0])"), // Do not stringify the form 149 | 'success' => new \yii\web\JsExpression("function(data) { 150 | if (data.status == true) 151 | { 152 | // process result 153 | } 154 | }"), 155 | ], 156 | 'options' => ['class' => 'btn btn-primary', 'type' => 'submit', 'id' =>'add-button'], 157 | ]); 158 | AjaxSubmitButton::end(); ?> 159 | ``` 160 | 161 | 162 | ### Widget's options 163 | 164 | Variable | Description | Type 165 | ------------ | ------------- | ------------- 166 | ajaxOptions | ajax options | Array 167 | options | HTML attributes and other options of the widget's container tag | Array 168 | tagName | the tag to use to render the button (by default is 'button'. You can specify, for example, 'a' tag) | String 169 | label | button's label | String 170 | icon | button's icon | String (e.g. 'fa fa-download') 171 | iconPosition | button icon position | const (ICON_POSITION_LEFT or ICON_POSITION_RIGHT) 172 | encodeLabel | whether the label should be HTML-encoded | Boolean 173 | clickedButtonVarName | js object name. It is unused when useWithActiveForm is enabled | String 174 | useWithActiveForm | whether the button should not be used with ActiveForm. the id of ActiveForm to use the button with | Boolean / String 175 | 176 | ## Installation 177 | ------------ 178 | 179 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 180 | 181 | Either run 182 | 183 | ``` 184 | php composer.phar require demogorgorn/yii2-ajax-submit-button "*" 185 | ``` 186 | 187 | or add 188 | 189 | ``` 190 | "demogorgorn/yii2-ajax-submit-button": "*" 191 | ``` 192 | 193 | to the require section of your `composer.json` file and run `composer update`. 194 | 195 | -------------------------------------------------------------------------------- /README.ru.md: -------------------------------------------------------------------------------- 1 | # AjaxSubmitButton для Yii 2 2 | ===================================== 3 | 4 | [![Latest Stable Version](https://poser.pugx.org/demogorgorn/yii2-ajax-submit-button/v/stable)](https://packagist.org/packages/demogorgorn/yii2-ajax-submit-button) 5 | [![Total Downloads](https://poser.pugx.org/demogorgorn/yii2-ajax-submit-button/downloads)](https://packagist.org/packages/demogorgorn/yii2-ajax-submit-button) 6 | [![License](https://poser.pugx.org/demogorgorn/yii2-ajax-submit-button/license)](https://packagist.org/packages/demogorgorn/yii2-ajax-submit-button) 7 | [![Monthly Downloads](https://poser.pugx.org/demogorgorn/yii2-ajax-submit-button/d/monthly)](https://packagist.org/packages/demogorgorn/yii2-ajax-submit-button) 8 | [![Yii2](https://img.shields.io/badge/Powered_by-Yii_Framework-green.svg?style=flat)](http://www.yiiframework.com/) 9 | 10 | 11 | AjaxSubmitButton это достаточно полезный и мощный виджет для создания ajax кнопки любой сложности, в т.ч. для работы с ActiveForm, обычной формой либо для использования в качестве самостоятельного элемента. Является аналогом ajaxSubmitButton в Yii1, но имеет ряд особенностей и полезных функций. 12 | 13 | ### Базовый пример 14 | 15 | Использование с произвольным виджетом в обычной форме (в данном случае произвольный виджет - Select2). 16 | 17 | Представление (view): 18 | ```php 19 | use demogorgorn\ajax\AjaxSubmitButton; 20 | 21 | 'uk-width-medium-1-1 uk-form uk-form-horizontal']); ?> 22 | 23 | 'country_code', 25 | 'data' => Country::getAllCountries(), 26 | 'options' => [ 27 | 'id' => 'country_select', 28 | 'multiple' => false, 29 | 'placeholder' => 'Choose...', 30 | 'class' => 'uk-width-medium-7-10'] 31 | ]); 32 | ?> 33 | 34 | 'Check', 36 | 'ajaxOptions' => [ 37 | 'type'=>'POST', 38 | 'url'=>'country/getinfo', 39 | 'success' => new \yii\web\JsExpression('function(html){ 40 | $("#output").html(html); 41 | }'), 42 | ], 43 | 'options' => ['class' => 'customclass', 'type' => 'submit'], 44 | ]); 45 | AjaxSubmitButton::end(); 46 | ?> 47 | 48 | 49 | 50 |
51 | ``` 52 | 53 | > Обратите внимание: элемент с id #output - это элемент, содержимое которого будет обновлено при удачном выполнении ajax запроса. 54 | 55 | Контроллер (controller): 56 | ```php 57 | public function actionGetinfo() 58 | { 59 | if(!isset($_POST['country_code']) || empty($_POST['country_code'])) 60 | return; 61 | 62 | $code = $_POST['country_code']; 63 | 64 | return $this->renderAjax('resultwidget', ['code' => $code]); 65 | } 66 | ``` 67 | 68 | ### Пример использования с ActiveForm и включенной клиентской валидацией (client validation) 69 | 70 | Представление: 71 | ```php 72 | $form = ActiveForm::begin([ 73 | 'id' => 'add-form', 74 | 'options' => ['class' => 'form-inline'], 75 | ]); 76 | 77 | ... 78 | 79 | AjaxSubmitButton::begin([ 80 | 'label' => 'Add', 81 | 'useWithActiveForm' => 'add-form', 82 | 'ajaxOptions' => [ 83 | 'type' => 'POST', 84 | 'success' => new \yii\web\JsExpression("function(data) { 85 | if (data.status == true) 86 | { 87 | closeTopbar(); 88 | } 89 | }"), 90 | ], 91 | 'options' => ['class' => 'btn btn-primary', 'type' => 'submit', 'id' =>'add-button'], 92 | ]); 93 | AjaxSubmitButton::end(); 94 | 95 | ActiveForm::end() 96 | ``` 97 | 98 | > Как видите использовать виджет с ActiveForm очень легко и просто - достаточно задать параметр id у ActiveForm, а также в параметре 'useWithActiveForm' указать id данной формы. (В данном примере id равен 'add-form', без символа '#'!). 99 | 100 | 101 | ### Клинтская валидация (Client validation) 102 | 103 | Как я указал выше, виджет может быть использован с ActiveForm с включенной клиентской валидацией (см. пример выше). Если вы хотите отключить валидацию на клиенте, установите параметру 'enableClientValidation' значение равное 'false'. 104 | 105 | ```php 106 | $form = ActiveForm::begin([ 107 | 'id' => 'filters-form', 108 | 'enableClientValidation' => false 109 | ]); 110 | ``` 111 | 112 | ### Использование Preloader 113 | 114 | Виджет можно использовать с произвольным preloader. 115 | 116 | ```php 117 | 'Check', 119 | 'ajaxOptions' => [ 120 | 'type'=>'POST', 121 | 'url'=>'country/getinfo', 122 | 'beforeSend' => new \yii\web\JsExpression('function(html){ 123 | ... show preloader... 124 | }'), 125 | 'success' => new \yii\web\JsExpression('function(html){ 126 | ... hide preloader ... 127 | }'), 128 | ], 129 | 'options' => ['class' => 'customclass', 'type' => 'submit'], 130 | ]); 131 | AjaxSubmitButton::end(); 132 | ?> 133 | ``` 134 | 135 | ### Опции виджета 136 | 137 | Параметр | Описание | Тип 138 | ------------ | ------------- | ------------- 139 | ajaxOptions | опции ajax запроса | Array 140 | options | HTML атрибуты и другие опции тега контейнера для виджета | Array 141 | tagName | имя тега для генерации кнопки (по умолчанию используется 'button'. Вы можете использовать, например, тег 'a') | String 142 | label | Текст кнопки | String 143 | encodeLabel | должен ли текст кнопки быть HTML-кодирован | Boolean 144 | clickedButtonVarName | имя объекта js. Не используется (игнорируется), когда параметр useWithActiveForm задан | String 145 | useWithActiveForm | должна ли кнопка использоваться в связке с ActiveForm. Указывается id ActiveForm, либо false, если не планируется использовать | Boolean / String 146 | 147 | ## Установка 148 | ------------ 149 | 150 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 151 | 152 | Either run 153 | 154 | ``` 155 | php composer.phar require demogorgorn/yii2-ajax-submit-button "*" 156 | ``` 157 | 158 | or add 159 | 160 | ``` 161 | "demogorgorn/yii2-ajax-submit-button": "*" 162 | ``` 163 | 164 | to the require section of your `composer.json` file and run `composer update`. 165 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demogorgorn/yii2-ajax-submit-button", 3 | "description": "AjaxSubmitButton renders an ajax button which is very similar to ajaxSubmitButton from Yii1.", 4 | "keywords": ["ajax", "submit", "button", "extension", "widget"], 5 | "homepage": "https://github.com/demogorgorn/yii2-ajax-submit-button", 6 | "type": "yii2-extension", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "Oleg Martemjanov", 11 | "email": "demogorgorn@gmail.com", 12 | "homepage" : "http://foreign.by" 13 | } 14 | ], 15 | "require": { 16 | "yiisoft/yii2": "*" 17 | }, 18 | "autoload": { 19 | "psr-4": { 20 | "demogorgorn\\ajax\\": "" 21 | } 22 | } 23 | } --------------------------------------------------------------------------------