GithubHelp home page GithubHelp logo

yiisoft / jquery-pjax Goto Github PK

View Code? Open in Web Editor NEW

This project forked from defunkt/jquery-pjax

143.0 23.0 40.0 907 KB

pushState + ajax = pjax

Home Page: http://pjax.herokuapp.com

License: MIT License

Ruby 1.86% Shell 0.84% JavaScript 92.68% HTML 4.63%
pjax ajax

jquery-pjax's Introduction

pjax = pushState + ajax, Yii 2.0 fork with enhancements

pjax is a jQuery plugin that uses ajax and pushState to deliver a fast browsing experience with real permalinks, page titles, and a working back button.

pjax works by fetching HTML from your server via ajax and replacing the content of a container element on your page with the loaded HTML. It then updates the current URL in the browser using pushState. This results in faster page navigation for two reasons:

  • No page resources (JS, CSS) get re-executed or re-applied;
  • If the server is configured for pjax, it can render only partial page contents and thus avoid the potentially costly full layout render.

Status of this project

jquery-pjax is largely unmaintained at this point. It might continue to receive important bug fixes, but its feature set is frozen and it's unlikely that it will get new features or enhancements.

Installation

pjax depends on jQuery 1.8 or higher.

Yii 2.0

There's no need to install library manually since it comes pre-installed with Yii 2.0.

bower

$ bower install yii2-pjax

standalone script

Or, add yii2-pjax to your app's bower.json.

  "dependencies": {
    "yii2-pjax": "latest"
  }

standalone

pjax can be downloaded directly into your app's public directory - just be sure you've loaded jQuery first. Download and include jquery.pjax.js in your web page:

curl -LO https://raw.github.com/yiisoft/jquery-pjax/master/jquery.pjax.js

Usage

$.fn.pjax

The simplest and most common use of pjax looks like this:

$(document).pjax('a', '#pjax-container')

This will enable pjax on all links on the page and designate the container as #pjax-container.

If you are migrating an existing site, you probably don't want to enable pjax everywhere just yet. Instead of using a global selector like a, try annotating pjaxable links with data-pjax, then use 'a[data-pjax]' as your selector. Or, try this selector that matches any <a data-pjax href=> links inside a <div data-pjax> container:

$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container')

Server-side configuration

Ideally, your server should detect pjax requests by looking at the special X-PJAX HTTP header, and render only the HTML meant to replace the contents of the container element (#pjax-container in our example) without the rest of the page layout. Here is an example of how this might be done in Ruby on Rails:

def index
  if request.headers['X-PJAX']
    render :layout => false
  end
end

If you'd like a more automatic solution than pjax for Rails check out Turbolinks.

Check if there is a pjax plugin for your favorite server framework.

Also check out RailsCasts #294: Playing with PJAX.

Arguments

The synopsis for the $.fn.pjax function is:

$(document).pjax(selector, [container], options)
  1. selector is a string to be used for click event delegation.
  2. container is a string selector that uniquely identifies the pjax container.
  3. options is an object with keys described below.
pjax options
key default description
timeout 650 ajax timeout in milliseconds after which a full refresh is forced
push true use pushState to add a browser history entry upon navigation
replace false replace URL without adding browser history entry
maxCacheLength 20 maximum cache size for previous container contents
version a string or function returning the current pjax version
scrollTo 0 vertical position to scroll to after navigation. To avoid changing scroll position, pass false. If set to true page will scroll to the pjax container. Can also be be a callback function with context and current hash passed in as parameters. E.g. function (context, hash) { if (!hash) return $(context).offset().top; }
scrollOffset 0 vertical offset that gets added to scrollTo. Can be a callback function with the current scrollTo value passed as a parameter.
type "GET" see $.ajax
dataType "html" see $.ajax
container CSS selector for the element where content should be replaced
url link.href a string or function that returns the URL for the ajax request
target link eventually the relatedTarget value for pjax events
fragment CSS selector for the fragment to extract from ajax response
pushRedirect false whether to add a browser history entry upon redirect
replaceRedirect true whether to replace URL without adding a browser history entry upon redirect
skipOuterContainers false When pjax containers are nested and this option is true, the closest pjax block will handle the event. Otherwise, the top container will handle the event
ieRedirectCompatibility true Whether to add X-Ie-Redirect-Compatibility header for the request on IE. Fixes IE error on 302 redirect without Location header

You can change the defaults globally by writing to the $.pjax.defaults object:

$.pjax.defaults.timeout = 1200

$.pjax.click

This is a lower level function used by $.fn.pjax itself. It allows you to get a little more control over the pjax event handling.

This example uses the current click context to set an ancestor element as the container:

if ($.support.pjax) {
  $(document).on('click', 'a[data-pjax]', function(event) {
    var container = $(this).closest('[data-pjax-container]')
    var containerSelector = '#' + container.id
    $.pjax.click(event, {container: containerSelector})
  })
}

NOTE Use the explicit $.support.pjax guard. We aren't using $.fn.pjax so we should avoid binding this event handler unless the browser is actually going to use pjax.

$.pjax.submit

Submits a form via pjax.

$(document).on('submit', 'form[data-pjax]', function(event) {
  $.pjax.submit(event, '#pjax-container')
})

$.pjax.reload

Initiates a request for the current URL to the server using pjax mechanism and replaces the container with the response. Does not add a browser history entry.

$.pjax.reload('#pjax-container', options)

$.pjax

Manual pjax invocation. Used mainly when you want to start a pjax request in a handler that didn't originate from a click. If you can get access to a click event, consider $.pjax.click(event) instead.

function applyFilters() {
  var url = urlForFilters()
  $.pjax({url: url, container: '#pjax-container'})
}

Events

All pjax events except pjax:click & pjax:clicked are fired from the pjax container element.

event cancel arguments notes
event lifecycle upon following a pjaxed link
pjax:click ✔︎ options fires from a link that got activated; cancel to prevent pjax
pjax:beforeSend ✔︎ xhr, options can set XHR headers
pjax:start xhr, options
pjax:send xhr, options
pjax:clicked options fires after pjax has started from a link that got clicked
pjax:beforeReplace contents, options before replacing HTML with content loaded from the server
pjax:success data, status, xhr, options after replacing HTML content loaded from the server
pjax:timeout ✔︎ xhr, options fires after options.timeout; will hard refresh unless canceled
pjax:error ✔︎ xhr, textStatus, error, options on ajax error; will hard refresh unless canceled
pjax:complete xhr, textStatus, options always fires after ajax, regardless of result
pjax:end xhr, options
event lifecycle on browser Back/Forward navigation
pjax:popstate event direction property: "back"/"forward"
pjax:start null, options before replacing content
pjax:beforeReplace contents, options right before replacing HTML with content from cache
pjax:end null, options after replacing content

pjax:send & pjax:complete are a good pair of events to use if you are implementing a loading indicator. They'll only be triggered if an actual XHR request is made, not if the content is loaded from cache:

$(document).on('pjax:send', function() {
  $('#loading').show()
})
$(document).on('pjax:complete', function() {
  $('#loading').hide()
})

An example of canceling a pjax:timeout event would be to disable the fallback timeout behavior if a spinner is being shown:

$(document).on('pjax:timeout', function(event) {
  // Prevent default timeout redirection behavior
  event.preventDefault()
})

Advanced configuration

Reinitializing plugins/widget on new page content

The whole point of pjax is that it fetches and inserts new content without refreshing the page. However, other jQuery plugins or libraries that are set to react on page loaded event (such as DOMContentLoaded) will not pick up on these changes. Therefore, it's usually a good idea to configure these plugins to reinitialize in the scope of the updated page content. This can be done like so:

$(document).on('ready pjax:end', function(event) {
  $(event.target).initializeMyPlugin()
})

This will make $.fn.initializeMyPlugin() be called at the document level on normal page load, and on the container level after any pjax navigation (either after clicking on a link or going Back in the browser).

Response types that force a reload

By default, pjax will force a full reload of the page if it receives one of the following responses from the server:

  • Page content that includes <html> when fragment selector wasn't explicitly configured. Pjax presumes that the server's response hasn't been properly configured for pjax. If fragment pjax option is given, pjax will extract the content based on that selector.

  • Page content that is blank. Pjax assumes that the server is unable to deliver proper pjax contents.

  • HTTP response code that is 4xx or 5xx, indicating some server error.

Affecting the browser URL

If the server needs to affect the URL which will appear in the browser URL after pjax navigation (like HTTP redirects work for normal requests), it can set the X-PJAX-URL header:

def index
  request.headers['X-PJAX-URL'] = "http://example.com/hello"
end

Layout Reloading

Layouts can be forced to do a hard reload when assets or html changes.

First set the initial layout version in your header with a custom meta tag.

<meta http-equiv="x-pjax-version" content="v123">

Then from the server side, set the X-PJAX-Version header to the same.

if request.headers['X-PJAX']
  response.headers['X-PJAX-Version'] = "v123"
end

Deploying a deploy, bumping the version constant to force clients to do a full reload the next request getting the new layout and assets.

jquery-pjax's People

Contributors

0b10011 avatar alexhill avatar anttimattila avatar aroben avatar arogachev avatar brianmario avatar cebe avatar chris123457 avatar defunkt avatar derekisbusy avatar drock avatar eval avatar freman avatar halida avatar josh avatar klevron avatar littke avatar mislav avatar qiangxue avatar rf- avatar samdark avatar samypesse avatar silverfire avatar sj26 avatar spantaleev avatar squeedee avatar sshirokov avatar tdhooper avatar tof06 avatar tonydspaniard avatar

Stargazers

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

Watchers

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

jquery-pjax's Issues

Timeout property has no effect

Hello!

I noticed that the timeout option has no effect on the behavior of the widget

            "name": "bower-asset/yii2-pjax",
            "version": "v2.0.5",
            "source": {
                "type": "git",
                "url": "https://github.com/yiisoft/jquery-pjax.git",
                "reference": "6818718408086db6bdcf33649cecb86b6b4f9b67"
            },

I'm using it this way

    <?php \yii\widgets\Pjax::begin([
        'id' => 'widget',
        'timeout' => 3000,
    ]) ?>

It looks fine in the page source code

    jQuery(document).pjax("#widget a", "#widget", {"timeout":3000,"push":true,"replace":false,"scrollTo":false});

But the option has no effect unless I set it globally via $.pjax.defaults.timeout = 3000;

Could it be an issue?

Cannot read property 'push' of undefined

My Code
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
];
public $js = [
'js/site.js',
'js/jquery-pjax.js',
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
'yii\widgets\PjaxAsset',
];
}

When no Pjax widget is used, then it throws an error "Cannot read property 'push' of undefined"

Issue with external script and PJAX

Currently the PJAX implementation has some flaws requiring all external scripts to be loaded before using it. See defunkt#331

I saw that you have already fixed the issue

Bug #23: Fixed loading of scripts in pjax containers (nkovacs, silverfire)

:) so my question now is when will the new version 2.0.6 of yiisoft/jquery-pjax be released since it solves this problem.

Problem with nested PJax. Fix.

I have a problem with nested pjax. I need to specify directly pjax-container in code. Because my code is blowing and become unreadably by overriding native pjax behaviours.

bower-asset.jquery.pjax.js.patch.txt

yii2-pjax.patch.txt.txt

The main goal of these patches are:

  1. Allow to specify pjax container for response by pjax-data attribute.
  2. Disallow bind events on elements inside nested containers.
  3. I tried to fight with multiple form submission on trigger form submit, but i found that pjax is good with this and closing submitted previous forms. So in Network is seen as posts gone, but in real sent only last. I have tried to add attribut on container when it pjax-processing and refuse next triggering, but failed, so i decided that pjax is good with multiple form submission.

Too many form submits

Sorry for broken english.
I have modal window. Inside him pjax-container and form loading by ajax request every time when i'mopen the window.

<div class="modal-dialog">
    <div class="modal-content">
        <div id="pjax-form-content" data-pjax-container="" data-pjax-timeout="1000">
            <form id="modal-form" >
                 ...
                 <button type="submit">Save</button>
             </form>
    </div>
</div>

Submitting form, closing modal window. Open modal-window again and try submit. Inside browser "developer tools" on tab "Network" i'm see 2 submit requests. Close window. Open. Submit. See 3 (!) submit requests... and more.. and more...

On close window event i'm bind next .js-function

$("document").ready(function(){
             var $modal = $(".modal-dialog").parent();
             $modal.one("hidden.bs.modal",function () {
                jQuery(document).off("submit", ".modal-dialog div[data-pjax-container] form[data-pjax]");
             });   
         });

After open and closing window i see inside browser "developer tools" on tab "Inspector" form and form's submit events. I found 2 events - from Yii and pjax. After closing window - event by Yii is deleted, but event from pjax not deleted. And after open window again i'm see 3(!) submit events, 1 from Yii and 2(!) same events from pjax. If i'm close window and open again - i'm see 3(!) same events on submit form by pjax.

I do not understand why this happens but I found a solution.

1st - inside widgets\Pjax.php change string

$js .= "\njQuery(document).on($submitEvent, $formSelector, function (event) {jQuery.pjax.submit(event, $options);});";

to

$js .= "\njQuery(document).off($submitEvent, $formSelector);
\njQuery(document).on($submitEvent, $formSelector, function (event) {jQuery.pjax.submit(event, $options);});";

2nd - On close window event i'm bind next .js-function

$("document").ready(function(){
             var $modal = $(".modal-dialog").parent();
             $modal.one("hidden.bs.modal",function () {
               var $id = $(".modal-dialog div[data-pjax-container]").attr("id"); 
                jQuery(document).off("submit", "#"+$id+" form[data-pjax]"); //for disable too times pjax submit                           });   
         });

I hope this will somehow help the author to solve this problem

Version confusion and backward incompatible changes

Yii 2.0.12 has the following dependency:

"bower-asset/yii2-pjax": "~2.0.1"

Today I did composer update and Pjax has been broken. I looked into the bower/yii2-pjax/bower.json file:

  "name": "yii2-pjax",
  "version": "2.0.7.1",
  "main": "./jquery.pjax.js",

version is 2.0.7.1. I learned the change log and found the line:

2.0.7 Sep 27, 2017
-----------------
...
- Merged updates from upstream. The update contains backward-incompatible changes, see [changes list](https://github.com/yiisoft/jquery-pjax/issues/55#issuecomment-310109608) to adjust your application accordingly. (silverfire)

I tried to override version of bower-asset/yii2-pjax by setting it in my project's composer file like this:

"bower-asset/yii2-pjax": "2.0.6",

But composer update shows the error:

  Problem 1
    - The requested package bower-asset/yii2-pjax 2.0.6 exists as bower-asset/yii2-pjax[2.0.7.1, v1.8.0-patch1, 2.0.8] but these are rejected by your constraint.
  Problem 2
    - yiisoft/yii2 2.0.12 requires bower-asset/yii2-pjax ~2.0.1 -> satisfiable by bower-asset/yii2-pjax[2.0.7.1, 2.0.8] but these conflict with your requirements or minimum-stability.
    - yiisoft/yii2 2.0.12 requires bower-asset/yii2-pjax ~2.0.1 -> satisfiable by bower-asset/yii2-pjax[2.0.7.1, 2.0.8] but these conflict with your requirements or minimum-stability.
    - Installation request for yiisoft/yii2 ^2.0.12 -> satisfiable by yiisoft/yii2[2.0.12].

I looked at another Yii project which is not updated last days, they have the same composer.json in yiisoft/yii2, BUT the different yiisoft/pjax/bower.json:

  "name": "yii2-pjax",
  "version": "2.0.6",
  "main": "./jquery.pjax.js",

Version is 2.0.6.

How this could happen? Build-version (even not minor) has backward incompatible changes and it updates silently? And why I can't roll back to 2.0.6 version?

full page refresh after redirect

I also have this issue. If I use $this->redirect in the controller, pjax will refresh the full page.

I've looked at the new pushRedirect and replaceRedirect options. Why is there a window.location.replace immediately after pushState and replaceState? That will cause a full page refresh.

Shouldn't it be something like this:

if (pushRedirect) {
    pushState(...);
} else if (replaceRedirect && pjax.options.history) {
    replaceState(...);
} else {
    location.replace() // old code that replaced after redirect
}

Edit: this isn't enough, because this just changes the url in the address bar, it doesn't actually load any new content. The redirect should be allowed to happen, but \yii\web\Response prevents it if checkAjax is true.

Не реагирует на атрибут data-pjax="0"

Использую стандартную кнопку для удаления

<a class="btn btn-default btn-xs" href="/post/delete?id=3" title="Удалить" aria-label="Удалить" data-confirm="Вы уверены, что хотите удалить этот элемент?" data-method="post" data-pjax="0">
    <span class="glyphicon glyphicon-trash"></span>
</a>

При нажатии на кнопку удалить вызывается событие handleSubmit() вместо handleClick()
происходит удаление элемента но без перезагрузки страницы

Пришлось откатиться до версии 3f20897 тут все ОК.

Wrong events lifecycle in case when ajax request is not async

When we use container reloading with synchronous ajax request

$.pjax.reload({container: '#pjax-container', async: false});

events fire in following order:

  • pjax:beforeSend
  • pjax:beforeReplace
  • pjax:success
  • pjax:complete
  • pjax:end
  • pjax:start
  • pjax:send

I think it's unexpected behaviour.

version: 2.0.7.1

Problem with page-specific JS assetbundles

I have been implementing PJAX using the yii2-pjax plugin quite successfully. I'm using it to only load the content on my page and keep the header and sidebar static, saving quite a few seconds on not having to reload the assets added to the header and the sidebar.

However, on some of my pages I'm using certain asset bundles to load in javascript only applied to those pages. When loading in the content with pjax these asset bundles are not being registered as I expected they would be. I'm wondering if there is any way to do what I want to do or if the only solution is to add a global javascript file that includes all functions? I would rather not do this as this might create quite a big file and a lot of unused code on certain pages.

This is how I've defined my content:

    <?php Pjax::begin() ?>
         AdminAsset::register($this);
         // Content here
    <?php Pjax::end() ?>

I've looked for the majority of the day and can't find a clean solution besides having one big application.js file or using inline javascript, both of which I would like to avoid.

Pjax redirect not working in Internet Explorer (IE11).

The controller code adds a header "X-Pjax-Url" that is successfully passed with the response.

The redirect for Pjax is handled through the pjax.js methods just fine in Chrome, Safari, and Firefox, but fails in IE11.

When I use the included IE debugger and view the response headers, the header is there and the url is correct, but IE11 isn't reading it.

The response error:
pjax-response-error

The response headers:
pjax-response-headers

Any ideas?

I have also asked this on the main Pjax GitHub page, but it hasn't received any responses.

$.pjax.reload(); seems to be not working anymore

Hi all,

After the last update of jquery.pjax.js (#8 (comment)) my gridview seems not refreshing anymore after clicking on actions button (I followed this tutorial : http://www.yiiframework.com/wiki/655/how-to-use-gridview-with-ajax/)
Here is a sample of my code (to display an action column) :

'class' => 'yii\grid\ActionColumn',
            'header' => 'Actions',
            'buttons' => [
                'reset' => function($url, $model) {
                    return Html::a(
                            '<span class="glyphicon glyphicon-repeat"></span>', '', [
                            'onClick' => "
                                    if (confirm('Are you sure you want to reset this?')) {
                                        $.ajax({
                                            cache    : false,
                                            url  : '" . $url . "',
                                            success  : function(response) {
                                                $.pjax.reload({container:'#translationGrid'}); //this line is not working anymore
                                            },
                                        });
                                    }
                                ",
                            'title' => Yii::t('yii', 'Reset')
                        ]
                    );
                }
            ],
            'template' => '{delete} {reset}'

It's look like that the line 389 hasn't the history: true option set :

if(!pjax.options.history) return; //history is set to false here

I propose to add the default value to true to the pjax() options (line145) :

function pjax(options) {
        options = $.extend(true, {history: true}, $.ajaxSettings, pjax.defaults, options)
        if ($.isFunction(options.url)) {
            options.url = options.url()
        }

Thank you for your feedback.

New version of pjax

Original jquery-pjax was updated recently to new version with some minor backward incompatibilities, will you accept pull request to this repo with those changes?

Can not work with jQuery3.x

Uncaught TypeError: Cannot read property 'push' of undefined
at jquery.pjax.js:981
at jquery.pjax.js:991

L981:$.event.props.push('state')

Fixed with these:

if ( $.event.props && $.inArray('state', $.event.props) < 0 ) {
  $.event.props.push('state');
} else if ( ! ('state' in $.Event.prototype) ) {
  $.event.addProp('state');
}

Add option to not deactivate focused element

There's code in jquery-pjax.js

document.activeElement.blur();

It can be very annoying if you type something into filter input, pjax reloads result grid and filter input loses focus. Moreover in this case backspace brings you to previous page instead of erasing character.
Can you add option to not deactivate focused element? It can be called "noBlur" for instance.
And then pjax will blur element only if this option is not set:

if (!noBlur) {
    document.activeElement.blur();
}

Js broken after go back by "back" button in browser

Pjax caches html content of any page by use jquery clone() function, the original html contents of each page will be overwritten by the next open page.
And when we click "back" button in browser, pjax paste cloned content. Of course, this cloned html, pasted from cache, does not contain any event handlers of original code and js does not work after that

PS: cached html does not contain inline script(wich can re-init event handlers), because yii2 paste inline scripts after container, but pjax cache container html only

PS2: The problem is not completely solved, even if the container will contain scripts, because pjax cache already rendered by js container. Therefore the html for javascript in the case of the first boot and after clicking on the "back" button will be different. This will contribute to errors and bugs.

Form getting submitted multiple time

Hi
I am using bootstrap modal popup and rendering the form into modal poup.
For the first time when modal popup opens everything is fine but the problem starts from second time. If again I opened the same modal popup without refreshing the page for adding the second record then 2 request being sent first one gets cancelled automatically while second one is executing but my controller receives both request and finally records getting added multiple time.
I Also mapped the bootstrap plugin assets and jquery plugin asset to FALSE. I feels this is happening just because of multiple rendering but my fix was not working

How to reproduce:

  1. create modal popup
  2. render a pjax based form using Jquery.load(); and call $("mymodal").modal('show');
  3. close the modal popup
  4. again open the same modal popup
  5. now fill the form values and try to submit the form (form should be in PJAX begin and end)
  6. records are adding two times. (If you open and close modal popup 3 time and at 4th records being added 4 time. Means number open calls same number of records are stored into database because same number of request are generating.

Extremely sorry for my english :) Please ignore if you found any grammatical mistakes

Thanks

Update fork

The original Pjax project has had some updates which would be worthwhile merging.
It now supports FormData where available which allows files to be uploaded.

Allow "data-pjax" attribute with no value in handleClick function

Related issue in Yii2 - yiisoft/yii2#13300. Should be synchronized here.

This check:

// Ignore links with data-pjax="0"
if ($(link).data('pjax') == 0) {
    return;
}

needs to be modified accordingly too, because "" == 0 will evaluate to true.

Can be:

$(link).data('pjax') === 0)

(data returns 0 as number).

Or in case of a string which is returend by attr for example:

$(link).attr('data-pjax') === '0'

Or maybe even better:

parseInt($(link).data('pjax')) === 0

Инициализация ActiveForm после PJAX

Добрый день!
В блоке Pjax имеется ListView и ActiveForm. Если валидатор на стороне сервера нашел ошибку, то клиенту возвращается форма с ее содержимым и соответствующие сообщения об ошибках. Когда пользователь начинает повторно вводить в данные форму, то оказывается, что валидаторы на стороне клиента не отрабатывают, т.е. вообще не реагируют на ввод данных, хотя соответствующий JS код передан. Я могу ошибаться, но мне кажется проблема в следующем. При первой загрузке страницы к форме прикрепляется атрибут yiiActiveForm - его наличие свидетельствует о том, что форма уже ранее была инициализирована и не требует повторной инициализации.
if ($form.data('yiiActiveForm')) { return; }
Когда форма повторно возвращается через Pjax и помещается в DOM документа, отрабатывает JS код инициализации формы, который пришел вместе с ее HTML кодом. Таким образом повторно отрабатывает init в yii.activeForm.js: запрашивается атрибут yiiActiveForm формы и jQuery успешно возвращает его и насколько я понял, возвращает его из кэша:
var cache = this.cache[ this.key( owner ) ]; return key === undefined ? cache : cache[ key ];
Мне удалось обойти эту проблему добавлением
<?php $this->registerJs('jQuery("#postDeliveryInfoForm").removeData("yiiActiveForm");'); ?>
в представлении формы сразу после ActiveForm::begin(). Получается после загрузки формы удаляется информация об ее инициализации (если конечно она есть) и форма успешно инициализируется, т.е. начинают работать валидаторы на стороне клиента при изменении содержимого полей.

В связи с этим вопрос: может стоит в методе инициализации формы поместить код if ($form.data('yiiActiveForm')) { $form.removeData('yiiActiveForm'); } чтобы форма повторно инициализировалась?

Problem with the browser Back button.

Hi, I'm implementing this example: http://www.yiiframework.com/wiki/772/pjax-on-activeform-and-gridview-yii2

But instead of adding records, i´m using it to search a model via GET.
Everything behaves the way it should, exept when I use the browser back button and reach the first state without any search, pjax is replacing the GridView with a duplicate of the search form, so I´m getting a page with two search forms and no GridView.

I've also tested it using a plain CRUD generated by Yii, and I get the same wrong behavior.

pjax reloads full page where is in modal

I'm using pjax from a view to reload a gridview without a full page reload.
In my JS code I call $.pjax.reload({container: "#container", async: false}); and it works fine on a normal view, I mean, full URL controller action.

But the same code makes a full page reload if I am using it in a modal.

To be more clear, the modal content is filled on a link:

$(document).on('click', '.showModal', function () {
    $('#myModal').modal('show')
            .find('#modalContent')
            .load($(this).attr('href'));
   return false;
});

Obviously in the controller action, the view is rendered with return this->renderAjax('view'); .

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.