Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed issue #518: Textarea and select value isn't preserved #542

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions jquery.pjax.js
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,21 @@ function uniqueId() {
}

function cloneContents(container) {
// Preserve textarea values
var textarea = findAll(container, "textarea")
textarea.text(function(i, text){return textarea[i].value})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isnt this missing a .each?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, text() has similar functionality: http://api.jquery.com/text/#text-function


// Preserve select values
findAll(container, "select").each(function(i, elem){
elem = $(elem);
var values = $(elem).val();
values = $.isArray(values) ? values : [values];
elem.find('option[selected]').attr('selected', false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not happy that this performs DOM changes on elements before they are cloned. How about just making these changes on the elements after they have been cloned?

elem.find('option').filter(function(){
return ($.inArray(this.value, values) !== -1);
}).attr('selected', true);
})

var cloned = container.clone()
// Unmark script tags as already being eval'd so they can get executed again
// when restored from cache. HAXX: Uses jQuery internal method.
Expand Down
157 changes: 157 additions & 0 deletions test/unit/pjax.js
Original file line number Diff line number Diff line change
Expand Up @@ -1099,4 +1099,161 @@ if ($.support.pjax) {
equal(frame.location.search, "")
})
})

asyncTest("preserves input value when going back and forth", 1, function() {
var count = 0
var frame = this.frame

frame.$.pjax({url: "form.html", container: "#main"})

frame.$("#main").on("pjax:end", function() {
count++
var field = frame.$("input[type=text]")

if (count == 1) {
// Form
field.val("changed")
frame.history.back()
} else if (count == 2) {
// Hello
frame.history.forward()
} else if (count == 3) {
// Form
equal(field.val(), "changed", "Field value is preserved")
start()
}
})
})

asyncTest("preserves textarea value when going back and forth", 1, function() {
var count = 0
var frame = this.frame

frame.$.pjax({url: "form.html", container: "#main"})

frame.$("#main").on("pjax:end", function() {
count++
var field = frame.$("textarea")

if (count == 1) {
// Form
field.val("changed")
frame.history.back()
} else if (count == 2) {
// Hello
frame.history.forward()
} else if (count == 3) {
// Form
equal(field.val(), "changed", "Field value is preserved")
start()
}
})
})

asyncTest("preserves checkbox value when going back and forth", 1, function() {
var count = 0
var frame = this.frame

frame.$.pjax({url: "form.html", container: "#main"})

frame.$("#main").on("pjax:end", function() {
count++
var field = frame.$("input[type=checkbox]")

if (count == 1) {
// Form
field.prop("checked", true)
frame.history.back()
} else if (count == 2) {
// Hello
frame.history.forward()
} else if (count == 3) {
// Form
ok(field.prop("checked"), "Field value is preserved")
start()
}
})
})

asyncTest("preserves checkbox value when going back and forth", 1, function() {
var count = 0
var frame = this.frame

frame.$.pjax({url: "form.html", container: "#main"})

frame.$("#main").on("pjax:end", function() {
count++
var field = frame.$("input[type=radio]")

if (count == 1) {
// Form
field.prop("checked", true)
frame.history.back()
} else if (count == 2) {
// Hello
frame.history.forward()
} else if (count == 3) {
// Form
ok(field.prop("checked"), "Field value is preserved")
start()
}
})
})

asyncTest("preserves select value when going back and forth", 1, function() {
var count = 0
var frame = this.frame

frame.$.pjax({url: "form.html", container: "#main"})

frame.$("#main").on("pjax:end", function() {
count++
var option = frame.$("select option:last")

if (count == 1) {
// Form
option.prop("selected", true)

frame.history.back()
} else if (count == 2) {
// Hello
frame.history.forward()
} else if (count == 3) {
// Form
//var option = frame.$("select option:last")
equal(option.prop("selected"), true, "Field value is preserved")
start()
}
})
})

asyncTest("preserves multiple select value when going back and forth", 3, function() {
var count = 0
var frame = this.frame

frame.$.pjax({url: "form.html", container: "#main"})

frame.$("#main").on("pjax:end", function() {
count++
var field = frame.$("select").prop("multiple", true)
var options = field.find("option")

if (count == 1) {
// Form
options.prop("selected", true)

frame.history.back()
} else if (count == 2) {
// Hello
frame.history.forward()
} else if (count == 3) {
// Form
options.each(function(){
equal($(this).prop("selected"), true, "Field value is preserved")
})
start()
}
})
})

}
18 changes: 18 additions & 0 deletions test/views/form.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<%= title 'Form' %>

<form action="env.html" method="GET">
<input type="text" value="foo">
<textarea>foo</textarea>

<input type="checkbox" value="foo">
<input type="radio" value="foo">

<select>
<option value="foo">foo</option>
<option value="bar">bar</option>
<option value="baz">baz</option>
</select>

</form>

<script type="text/javascript">window.parent.iframeLoad(window)</script>