Git Product home page Git Product logo

jquery-ajax-unobtrusive's Introduction

IMPORTANT: This repository is in maintenance mode. We do not work, nor plan to work on any new features. Only security and critical bug fixes will be worked on.

jQuery Unobtrusive Ajax

The jQuery Unobtrusive Ajax library complements jQuery Ajax methods by adding support for specifying options for HTML replacement via Ajax calls as HTML5 data-* elements.

This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the Home repo.

Remember to make your changes to only the src file. Use ".\build.cmd" to automatically generate the js file in dist directory, minify the js file, create a .nupkg and change the version in the package.json if needed.

To stage for a release, update the "version.props" file and run ".\build.cmd" (see Release Checklist here).

jquery-ajax-unobtrusive's People

Contributors

abelperezok avatar ajaybhargavb avatar damianedwards avatar eilon avatar jbagga avatar kichalla avatar mkartakmsft avatar ryanbrandenburg avatar spudcz avatar terrajobst 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jquery-ajax-unobtrusive's Issues

Debounce?

How can I specify a time to wait between ajax calls. When the user is typing its firing off a ton requests like crazy.

Consider restricting the contentType of the data that will get inserted/replaced when data-ajax-update is declared

Currently, upon successful ajax call, the library calls asyncOnSuccess method, which, if data-ajax-update attribute is set, will update (or replace, or add before/after) the target specified in this attribute with the returned data from the call. The update happens regardless if the data is html or not (the only check is done for it being a javascript content). So in case of, for example, contentType of application/json or binary data, it will still be treated like html.

This behavior makes implementing server responses that return different contentType depending on the form request impossible, because each response will get inserted into html. The asyncOnSuccess method is also called unconditionally, before user-defined success callback is called and thus it's impossible to override. One could argue that this can be avoided by not specifying the data-ajax-update attribute in the first place, but this attribute gets declared statically, in design time, while the contentType of the response may be set dynamically by the server, eg. return text/html if the form had validation errors (this would replace the form content, in which case the attribute is needed) or return application/json with processing data for javascript code if the post was successful (in which case the html update should be skipped).

My proposal is to check the data's contentType if it's text/html and only then manipulate the html. This would still be within the intent of your library to handle html updates, but will be constrained to content that is in fact updateable. (It might be also considered to allow text/plain to be handled as well, although in this case I'd suggest using $.text() instead of $.html() when doing the manipulation).

What do you think about it?

Undefined handlers cause error when unsafe-eval is restricted by the CSP header

Undefined handlers (OnBegin, OnSuccess, etc.) cause a browser evaluation error when unsafe-eval is restricted by the CSP header.

If you modify all of the text in the handlers to functions instead of JavaScript code then those handlers that contain functions will no longer be blocked by the browser (window.stop [function] vs window.stop() [code needing evaluation]). However, the issue is that the handlers that are left blank will be blocked by the browser and cause an error.

Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive:

Related to Issue #23.

Update NPM Package

Could you please update this package also on NPM to the latest version?
Kind regards

Remove Jquery dependency

It would be nice to rewrite this in pure javascript (maybe have jquery optional) as it is very useful to in conjuction with asp.net core / .net 5 view components (it basically elimates the need to write javascript!).

cdn

do we have cdn-hosted copy of this library?

Scripts are not evaluated using data-ajax-mode="before" or data-ajax-mode="after"

When I use @Ajax.ActionLink with InsertionMode = InsertionMode.InsertAfter or InsertionMode = InsertionMode.InsertAfter to load PartialView, script tags loaded from the server are not evaluated (but with InsertionMode = InsertionMode.Replace and InsertionMode = InsertionMode.ReplaceWith scripts are evaluated).

It happens because the native DOM API (not jQuery) is used in this code block:
https://github.com/aspnet/jquery-ajax-unobtrusive/blob/master/src/jquery.unobtrusive-ajax.js#L57-L68

I suggest fixing this scenario using a jQuery API for the data-ajax-mode="before" and data-ajax-mode="after" modes.

Ajax.BeginForm not re-initialized after dynamic element update

I have code like this:

            <div id="fooId">

                @using (Ajax.BeginForm("ChangeRating", "Leads", new AjaxOptions { AllowCache = false, HttpMethod = "POST", InsertionMode = InsertionMode.ReplaceWith, UpdateTargetId = $"fooId", OnBegin = "fooLoder" }))
                {
                    @Html.AntiForgeryToken()
                    <select name="fooSelect" onChange="$(this).closest('form').trigger('submit');">
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                        <option value="4">4</option>
                        <option value="5">5</option>
                    </select>
                }

            </div>

After selectbox change form is submitted and fooLoder is called onBegin. Then content is replaced with new content. div with id fooId is in code after update. If I change select again, form gets submitted, but fooLoder is not called.

I think ajax events are not bound when the content is dynamically replaced. How to fix that?

Property data-ajax-cache is not resolved right

line 94
cache: !!element.getAttribute("data-ajax-cache")

When I have anchor defined like this:
<a href="..." data-ajax="true" data-ajax-cache="false">...</a>
then the javascript code above sets cache to true.

element.getAttribute("data-ajax-cache") returns string "false"
!element.getAttribute("data-ajax-cache") returns boolean false
!!element.getAttribute("data-ajax-cache") returns boolean true

Consider changing line 94 to this:
cache: (element.getAttribute("data-ajax-cache") || "").toLowerCase() === "true"

Support formaction attribute

This is an issue in support of the PR #36 . I hereby present a concrete case in which my personal experience with the product would improve if the functionality shown in that PR was merged.

Currently, when having a form like this one:

<form action="/Management/Products/Edit/A001"
    data-ajax="true"
    data-ajax-method="Post"
    data-ajax-mode="replace"
    data-ajax-update="#preview-container"
    id="form0" method="post">
    <div class="row">
        <section class="col-md-9">
            <h2>Edit</h2>
            <div class="form-row">
                <div class="form-group col-md-12">
                    <label for="Name">Name</label>
                    <input class="text-box single-line" id="Name" name="Name" type="text" value="Test" />
                </div>
            </div>
        </section>
        <section class="col-md-3">
            <h2>Preview</h2>
            <div id="preview-container">
                <product-card code="A001" name="Test"></product-card>
            </div>
        </section>
    </div>
    <a class="btn btn-dark" href="/Management/Products">Cancel</a>
    <button type="submit" class="btn btn-secondary" formaction="/Management/Products/Preview">
        Preview
    </button>
    <button type="submit" class="btn btn-success">
        Save
    </button>
</form>

clicking on the "Preview" button causes a request to be isssued to /Management/Products/Edit/A001 instead of /Management/Products/Preview . The second case would be desired as that is the destination that would be hit if we were using synchronous, old-style forms without unobtrusive jquery-ajax support.

Supporting formaction natively would eliminate the need to sometimes come up with workarounds to use a library that is really good in every other aspect I had the chance to encounter.

Ajax redirect update

I like using ajax for my form submissions. It allows me to update the page with the result for a nice user experience.

However, sometimes you need to redirect to a new location and not just update the existing page. In the past in my own ajax calls I used to "unofficial" status code of "278" for this. This has been used for about 4 years in the community. Its a "success" code so the browsers don't try to handle it. Adding this functionality into the unobtrusive library is pretty simple.

In the "asyncRequest" method, I just updated the "success" function to:

success: function (data, status, xhr) {
    if (xhr.status === 278)
    {
        var location = xhr.getResponseHeader("Location") || window.location.href;
        window.location.replace(location);

        return;
    }
    asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
    getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(element, arguments);
},

Then you just have to return a status code 278 with a "Location" header containing the Url of the redirect. Works great.

Might be worth adding to the base library.

A second options (that requires no library update) is to return a "278" status code, with the "Location" header, but ALSO set the "Content-Type" to "application/x-javascript". The library has a check for this in the "asyncOnSuccess" and will NOT run the "success" logic. But it WILL run the "data-ajax-complete" method. Then you can add your own status code "278" check and do the redirect.

I like the first option .. seems cleaner.

submit buttons html5 formnovalidate attribute is not respected

And because of that, a form is still validated even though you mark a submit button with the formnovalidate attribute.
Through reading the source i learned that a 'cancel' css class should be used.

Please extend this functionality to also work with the formnovalidate html5 attribute. (If you want backwards compat). Or better, throw the 'cancel' css class 'hack' out, and only support the attribute.

I already fixed it in my own version. So if you want I can do a PR.

Doesn't work in Razor Pages form with buttons with different handlers

asp-page-handler can be set on the form, but it doesn't work if it's set on the buttons inside the form

<form data-ajax="true" data-ajax-method="Post" data-ajax-mode="replace"
      data-ajax-update="#content" data-ajax-loading="#loading" data-ajax-loading-duration="300"
      data-ajax-complete="Complete">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Domain.Name" class="control-label"></label>
        <input asp-for="Domain.Name" class="form-control" />
        <span asp-validation-for="Domain.Name" class="text-danger"></span>
    </div>
    <div class="form-group">
        <input asp-page-handler="Create" type="submit" value="Create" class="btn btn-default" />
        <input asp-page-handler="Edit" type="submit" value="Edit" class="btn btn-default" />
    </div>
</form>

Disable proxy safe override

The isMethodProxySafe function limits methods to GET or POST. Is it possible to add PUT, PATCH and DELETE to allow REST support?

If not, can you add support for an attribute named data-ajax-method-override? It would default to true, but could be set to false to ignore.

Add the easy ability to not autogenerate X-Requested-With and _ for GET requests

Here is my example fiddle illustrating this.

I want to consume FIPS block data from the census bureau. The URL should look like:

https://data.fcc.gov/api/block/find?showall=true&latitude=40.6590165&longitude=-74.2896593

However, if I use unobtrusive ajax on a GET form, it adds two paramaters, _ and X-Requested-With I get blocked like so:

image

I'd like a nicer method than removing it after its added with BeginForm. as discussed here.

Extensibility for "custom" update of data

Currently there is no way to change the way the new data is updated in the DOM. You have:

BEFORE
AFTER
REPLACE-WITH

But that just gives the basics. I wont over the source and added in a new "CUSTOM" update mode, and a new function.

data-ajax-mode="custom"
data-ajax-custom="myCustomFunction"

All it took was this (in asyncOnSuccess, right below the "REPLACE-WITH" case) :

case "REPLACE-WITH":
        $(update).replaceWith(data);
        break;
case "CUSTOM":
        getFunction(element.getAttribute("data-ajax-custom"), ["update", "data"]).apply(element, [update, data]);
        break;
default:
        $(update).html(data);
        break;

and then can write my own transition code:

function scalingElementTransition(element, data)
{
    // Get the original page that we have in the wizard that we want to replace
    var original = $(element);

    // Clone the element and replace the html inside it with our new data.
    var newPage = original.clone().css("display", "none").html(data);

    // Insert this new data into the DOM.  Its hidden, so we wont see it.
    newPage.insertAfter(original);

    // Slide out the old page and slide in the new page.
    original.stop(true, true).toggle("scale", { percent: 0, origin: ["middle", "center"] }, 500);
    newPage.stop(true, true).toggle("scale", { percent: 0, origin: ["middle", "center"] }, 500, function () {
        // remove the old page from the DOM once it is hidden.
        original.remove();
    });
}

But you can write your own transition code...

Anyone think this might make a valid update in the official source?

Any docs for the lib?

Is there any docs/sample code for the lib using asp.net core? Maybe someone could provide a small README or a dedicated chapter on the wiki.

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.