Commit 38f7196e authored by S Anand's avatar S Anand

BUG: checkboxes, inputs, forms trigger urlfilter #119 @karmanya.aggarwal

parent 30c3e9e7
Pipeline #77014 passed with stage
in 2 minutes and 14 seconds
......@@ -4,8 +4,9 @@
Example: Let's say the following HTML is on the page `/?city=NY`.
<!-- render:html -->
```html
<a class="urlfilter" href="?name=John">Link</a>
<a class="urlfilter" href="?name=John">Add ?name=John to URL</a>
<script>
$('body').urlfilter()
</script>
......@@ -26,21 +27,51 @@ current page URL instead of replacing it.
For example:
<!-- render:html -->
```html
<a class="urlfilter" href="?city=NY"> Change ?city= to NY</a>
<a class="urlfilter" href="?city=NY" data-mode="add"> Add ?city= to NY</a>
<a class="urlfilter" href="?city=NY" data-mode="del"> Remove NY from ?city=</a>
<a class="urlfilter" href="?city=NY" data-mode="toggle"> Toggle NY in ?city=</a>
<a class="urlfilter" href="?city=NY" data-target="pushState">Change ?city= to NY using pushState</a>
<a class="urlfilter" href="?city=NY" data-target="#"> Change location.hash, i.e. #?city= to NY</a>
<a class="urlfilter" href="?city=NY" data-target="iframe"> Change iframe URL ?city= NY</a>
<iframe src="?country=US"></iframe>
<a class="urlfilter" href="?city=NY" data-target=".block"> Use AJAX to load ?city=NY into .block</a>
<div class="block" src="?country=US"></div>
<script>
$('body').urlfilter() // Activate all the .urlfilter elements above
</script>
<li><a class="urlfilter" href="?city=NY"> Change ?city= to NY</a></li>
<li><a class="urlfilter" href="?city=NY" data-mode="add"> Add ?city= to NY</a></li>
<li><a class="urlfilter" href="?city=NY" data-mode="del"> Remove NY from ?city=</a></li>
<li><a class="urlfilter" href="?city=NY" data-mode="toggle"> Toggle NY in ?city=</a></li>
<li><a class="urlfilter" href="?city=NY" data-target="pushState">Change ?city= to NY using pushState</a></li>
<li><a class="urlfilter" href="?city=NY" data-target="#"> Change location.hash, i.e. #?city= to NY</a></li>
```
This works with `input`, `select` and `form` elements as well.
<!-- render:html -->
```html
<p><label><input type="checkbox" class="urlfilter" name="a" value="1" data-mode="toggle" data-target="#"> a=1</label></p>
<p>
<label><input type="radio" class="urlfilter" name="b" value="1" data-target="#"> b=1</label>
<label><input type="radio" class="urlfilter" name="b" value="2" data-target="#"> b=2</label>
</p>
<p><label><input type="range" class="urlfilter" name="c" data-target="#"> c=</label></p>
<p>
<select name="d" class="urlfilter" data-target="#">
<option></option>
<option>1</option>
<option>2</option>
</select>
</p>
<p>
<form class="urlfilter" data-target="#">
<input name="x" placeholder="x value">
<input name="y" placeholder="y value">
<button name="z" value="z2" type="submit">Submit</button>
</form>
</p>
```
You can target an IFrame or DOM element to change the URL:
<!-- TODO: check these examples. Not working -->
```html
<p><a class="urlfilter" href="?city=NY" data-target="iframe">Change iframe URL ?city= NY</a></p>
<iframe src="?country=US"></iframe>
<p><a class="urlfilter" href="?city=NY" data-target=".block"> Use AJAX to load ?city=NY into .block</a></p>
<div class="block" src="?country=US"></div>
```
......@@ -64,6 +95,8 @@ Triggers support these attributes:
- `toggle` - toggles the query key and value combination
- `data-remove="true"`: removes query parameters without values. e.g. `?x&y=1` becomes `?y=1`
- `data-src` changes which attribute holds the current URL when `data-target=` is a selector. Default: `src`
- for input fields like checkboxes, an `id` or `name` and the `value` attribute is mandatory. e.g
`<input type="checkbox" id="checkbox" value="x">` will add `?checkbox=x` to the URL
Containers support these attributes:
......
import { parse } from './url.js'
import { hasdata } from './_util.js'
var container_options = {
attr: 'href',
event: 'click change submit',
selector: '.urlfilter',
src: 'src'
}
var event_namespace = '.urlfilter'
export function urlfilter(options) {
options = options || {}
var $self = this
// If there are no elements in the selection, exit silently
if ($self.length == 0)
return
var doc = $self[0].ownerDocument
var attr = options.attr || $self.data('attr') || 'href'
var event = options.event || $self.data('event') || 'click'
var selector = options.selector || $self.data('selector') || '.urlfilter'
var default_src = options.src || $self.data('src') || 'src'
var default_mode = options.mode || $self.data('mode')
var default_target = options.target || $self.data('target')
var default_remove = options.remove || hasdata($self, 'remove')
var off = options.off || hasdata($self, 'off')
var settings = $.extend({}, container_options, options || {}, this.dataset)
var default_remove = settings.remove || hasdata($self, 'remove')
var events = settings.event.split(/\s+/).map(function (v) { return v + event_namespace }).join(' ')
// options.location and options.history are used purely for testing
var loc = options.location || (doc.defaultView || doc.parentWindow).location
var hist = options.history || (doc.defaultView || doc.parentWindow).history
if (off)
return $self.off(event + '.urlfilter')
var loc = settings.location || (doc.defaultView || doc.parentWindow).location
var hist = settings.history || (doc.defaultView || doc.parentWindow).history
return $self
.on(event + '.urlfilter', selector, function (e) {
e.preventDefault()
.on(events, settings.selector, function (e) {
var $this = $(this),
mode = $this.data('mode') || default_mode,
target = $this.data('target') || default_target,
src = $this.data('src') || default_src,
remove = hasdata($this, 'remove', default_remove)
var href
if (e.type == 'click')
href = $this.attr(attr)
else if (e.type == 'submit')
href = '?' + $this.serialize()
else if (e.type == 'input' || e.type == 'change') {
mode = $this.data('mode') || settings.mode,
target = $this.data('target') || settings.target,
src = $this.data('src') || settings.src,
remove = hasdata($this, 'remove', default_remove),
href
if (e.type == 'change' || $(e.target).is(':input:not(:button)')) {
var key = encodeURIComponent($this.attr('id') || $this.attr('name'))
var val = encodeURIComponent($this.val())
href = '?' + key + '=' + val
}
else if (e.type == 'submit' || $(e.target).is('form')) {
e.preventDefault()
href = '?' + $this.serialize()
}
else if (e.type == 'click') {
if ($(e.target).is('a'))
e.preventDefault()
href = $this.attr(settings.attr)
} else
return
var url = parse(href),
q = url.searchList
......@@ -62,14 +62,12 @@ export function urlfilter(options) {
return result.toString()
}
/*
If the target is... the URL is get/set at
------------------------ ---------------------
unspecified (=> window) location.href
'pushState' location.href
'#' location.hash
anything else $(target).data(src)
*/
// If the target is... the URL is get/set at
// ------------------------ ---------------------
// unspecified (=> window) location.href
// 'pushState' location.href
// '#' location.hash
// anything else $(target).data(src)
if (!target)
loc.href = target_url(loc.href)
else if (target == '#')
......
......@@ -4,6 +4,8 @@
<head>
<title>urlfilter tests</title>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.css">
<script src="../node_modules/bootstrap/dist/js/bootstrap.js"></script>
<script src="../dist/event.min.js"></script>
<script src="../dist/urlfilter.min.js"></script>
<script src="../node_modules/component-emitter/index.js"></script>
......@@ -69,6 +71,9 @@
<i class="urlfilter base" href="?x=1">?x=1</i>
<div class="urlfilter base" href="?x=1">?x=1</div>
<button class="urlfilter base" href="?x=1">?x=1</button>
<div>
<input type="checkbox" class="urlfilter base" data-mode="toggle" id="checkbox" value="x" checked>
</div>
<script>
tape('clicking any element sets location.href to a page with an UPDATED URL', function (t) {
check(t, 'a.urlfilter.base', 'href', '?y=1', 'y=1&x=1')
......@@ -76,6 +81,10 @@
check(t, 'div.urlfilter.base', 'href', '?y=1', 'y=1&x=1')
check(t, 'button.urlfilter.base', 'href', '?y=1', 'y=1&x=1')
})
tape('Events on checkbox should set location.href to a page with UPDATED URL', function(t){
check(t, '#checkbox', 'href', '?y=1', 'y=1&checkbox=x')
check(t, '#checkbox', 'href', '?y=1', 'y=1&checkbox=x', 'change')
})
tape('the URL is updated, irrespective of the current URL', function (t) {
check(t, 'a.urlfilter.base', 'href', '', 'x=1')
check(t, 'a.urlfilter.base', 'href', '?x', 'x=1')
......@@ -85,7 +94,7 @@
})
</script>
<a class="urlfilter def x1" href="?x=1" data-mode="">set ?x=1</a>
<a class="urlfilter def x1" href="?x=1" data-mode="">set ?x=1< fddfgdf</a>
<a class="urlfilter add x1" href="?x=1" data-mode="add">add ?x=1</a>
<a class="urlfilter tog x1" href="?x=1" data-mode="toggle">toggle ?x=1</a>
<a class="urlfilter del x1" href="?x=1" data-mode="del">toggle ?x=1</a>
......@@ -174,24 +183,24 @@
<!-- .default-section -->
<section class="default-input-section" data-event="input">
<input type="range" class="urlfilter base" name="slider">
<input type="range" class="urlfilter slider" name="slider">
<script>
$('.default-input-section').urlfilter({ location: loc, history: hist, event: 'input' })
tape('clicking any element sets location.href to a page with an UPDATED URL', function (test) {
test.plan(3)
test.test('test slider no input', function (t) {
check(t, 'input.urlfilter.base', 'href', '?slider=50', 'slider=50', 'input')
check(t, 'input.urlfilter.slider', 'href', '?slider=50', 'slider=50', 'input')
})
// update slider
test.test('test slider with change in val', function (t) {
$('input.urlfilter.base').val(80)
check(t, 'input.urlfilter.base', 'href', '?slider=80', 'slider=80', 'input')
$('input.urlfilter.slider').val(80)
check(t, 'input.urlfilter.slider', 'href', '?slider=80', 'slider=80', 'input')
})
// update name attr and update slider
test.test('test slider with change in name of <input> element', function (t) {
$('input.urlfilter.base').attr('name', 'slider_renamed')
$('input.urlfilter.base').val(60)
check(t, 'input.urlfilter.base', 'href', '?slider_renamed=620', 'slider_renamed=60', 'input')
$('input.urlfilter.slider').attr('name', 'slider_renamed')
$('input.urlfilter.slider').val(60)
check(t, 'input.urlfilter.slider', 'href', '?slider_renamed=620', 'slider_renamed=60', 'input')
})
})
</script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment