jQuery Sortable freezes after AJAX html replace - jquery-ui

jQuery Code: I removed all my Sortable settings. If you feel they are pertinent I can put them back in.
$('#navsort').sortable({ ... });
$("#content").on('click', '#submit_menu', function (event){
event.preventDefault();
$.ajax({
type: "POST",
url: "menu-ajax.php",
data: { data:$('#form').serialize() }
}).done(function (response) {
$('#content').hide().html(response).fadeIn('slow');
});
});
HTML Code: This is a simplified version because the real code has lots of PHP and other stuff going on.
<div id="content">
<form method="post" id="form">
Save
<ol id="navsort">
...
</ol>
</form>
</div>
As you can see the entire form, including the elements attached to Sortable, are replaced (with an identical copy of itself) via AJAX when the form is submitted. This is when Sortable stops working.
I understand that the new form was not part of the DOM when Sortable was initialized and so its not attached despite being identical to the form it replaced. I also understand how .on() is used to delegate between elements that are present when the page first loads and those added afterwards. What I do no understand is how to apply this concept to the initialization of Sortable.
I got it to work with a dirty hack, but I want to understand the right way.
Dirty Hack:
function dirtyhack(){
$("selector").on('event', 'target', function (){ ... });
}
dirtyhack();
$("#content").on('click', '#submit_menu', function (event){
event.preventDefault();
$.ajax({
type: "POST",
url: "menu-ajax.php",
data: { data:$('#form').serialize() }
}).done(function (response) {
$('#content').hide().html(response).fadeIn('slow');
dirtyhack();
});
});
So Sortable is initialized when the page loads and reinitialized when AJAX is done replacing the elements Sortable is attached to. Maybe this is right, but it feels wrong.
Disclosure: I am actually using the nestedSortable plugin in place of Sortable, but the plugin author claims that "All jQuery Sortable options, events and methods are available" through his plugin. I also did switch to the standard Sortable Widget to test and had the same issue, so I do not think its the plugin.
Plugin URL: https://github.com/mjsarfatti/nestedSortable/tree/2.0alpha

Related

JQuery Mobile - How can I pass data context from a listview item to another page?

I'm generating a listview of "products" dynamically with some JSON data I'm getting using ajax request. When an user clicks on a item I want to take them to another page where all of the products details would be displayed.
$(document).delegate("#store", "pageinit", function() {
getProducts('',
function(data){
let products = data.products;
storeProducts(products);
$(".product-list").html('');
$.each(products, function(i, item){
$(".product-list").append(`
<li>
<a href="#product">
<img src="${item.picture}" alt="">
<h2>${item.prod_name}</h2>
<p>${item.prod_desc}</p>
<small>Price: <strong>€${item.unit_price}</strong></small>
</a>
</li>
`).listview("refresh");
});
},
function(e){
console.log(e);
},
function(data){
console.log('always');
});
});
Now the problem is that I don't see how to pass the data context of a list item to another page (#product) in order to populate it with the corresponding information. I have seen a few approaches to similar use cases but they seem a bit ugly to me.
I believe this is a very basic feature for a web/mobile application nowadays; However JQuery Mobile doesn't seem to make it easy for a developer to implement such feature. Any plugin/library I can use to implement this?
Thanks in advance.
As you are creating the list items dynamically, this could be easily done by adding your own custom data attribute, like this:
'<li data-id="+${item.prod_id}+">'
Then, you can get the product context this way:
$(document).on("vclick", ".product-list li>a", function() {
var id = $(this).data("id");
...get the product context by id
});
Here is an example with working demo: https://stackoverflow.com/a/43915438/4845566
BTW, just two small hints aside :
if you create the html token by using [].join("") you will avoid the extra spaces/tabs in markup.
You can also refresh the listview just one time, out of the products loop.

jQuery Mobile: Submitted form not staying on "thank you" page

I'm new to jQuery mobile, I have just started using it for a WordPress site that's supposed to be only used via a smartphone. I like the way it looks now that I added jQm to the equation.
The problem I have is that after I submit a form, it correctly takes me to the "thank you" page, which at this point is just a single line of text reading "thank you for playing", but immediately after that it goes back to the original form where it came from. I might not be able to explain this better, so I recorded a video with the issue here: http://screencast.com/t/QMD0BProSg
If I disable ajax with "$.mobile.ajaxEnabled = false;" it works, meaning it doesn't go back to my form, but having ajax enabled and working the way it's supposed to, will get rid of a couple of other issues I have. Fixing this behaviour will save me a lot of time!
Here's the HTML:
<form id="stop-spin" action="/thanks-for-playing" method="post">
<input type="hidden" id="stop-spin-nonce" name="stop-spin-nonce" value="c96ef6a79f">
<input type="hidden" name="_wp_http_referer" value="/spinner/">
</form>
<div class="play-button">
</div>
I removed the extra elements for the sake of simplicity, but it's worth noting that my form doesn't have a button inside, what I do is capture the Click event of the #stop-rotation anchor via jQuery and I do the form submit there.
Here's my jQuery:
$( document ).on( 'pageinit ready', function() {
$( document ).on( 'click', '.play-button a#stop-rotation', function() {
$( '#stop-spin' ).submit();
});
});
I might be missing something obvious here, can anyone help me out with this?
At the moment this little app is local only, but I can try and build a fiddle or upload to my test server if anyone wants to take a look at it as a whole.
Thanks in advance for any assistance
Corrected your code, this should do the job. You'll never need the ready() event in JQM, replace it with pageinit() or pageshow() for example.
$( document ).on( 'pageinit', function() {
$( '.play-button a#stop-rotation' ).on( 'click', function() {
$( '#stop-spin' ).submit();
return false;
});
});

bind a jquery plugin to ajax loaded content

I've used sortable/portlet jquery ui plugin on my website. I load some boxes after the page is loaded via ajax. but they don't look like the boxes appears at the page load time. I know the problem loading via ajax and bind issue. But how can I solve it?
You're ajax call has a success method which you can use to bind to elements that have been dynamically added.
For example you could do
$.ajax({
url: 'ajax/test.html',
success: function(data) {
$('.result').html(data);
$(".column").sortable({ connectWith: ".column", cursor: 'crosshair' });
}
});

how to submit a php/html form loaded into a dialod using .load()

Am trying to understand jquery. Am a bit slow, maybe cause I come from a COBOL background.
I learn as i do, instead of just reading. php, jquery are all just hobbies for me
I used to have these update form pages. I wanted to try and put them in dialogs.
I trying using Dialog with an I frame, I did not like it, The iframes were very slow to load, of of the pages being loaded contained jquery tabs, which where even slower to load. And several other problems.
So I trying moving away from iframes. I stripped the pages and kept the meat(the body of my php/html file)(minus the body tag), So now I load a short version of my Form onto the dialog, It loads beautifully and looks good.
So next I wanna submit my for data, this is where I am a bit lost....
I am guesting I have to use Ajax, but on returning from Ajax with a OK/Fail message I am lost again.
My submit buttons were not jquery dialog buttons, Must they be so?
Must I use buttons:
{
"Save" : function () {
.....
"Close" : function () {
$(this).dialog("close");
.....
}
These are ugly and I have less control on where to place them and how the look.
All you need to do is make sure you have a form in your dialog box.
The, add a listener on your form. Let's say you have
<form id="myForm">
<input id="myInput" name="myName" type="text" />
</form>
Then you would add a listener :
$("#myForm").die().live('submit',function(e) {
e.preventDefault();
$.ajax({
type : POST,
url : localhost:8080/myUrl,
dataType : 'json',
cache: false,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
data : $("#myForm").serialize(),
success : function(){ //do what you want here, like displaying validation errors...},
error:function (xhr, ajaxOptions, thrownError){ //manage ajax errors}
});
return false;
});
So your Save button is just a plain input type="submit"
Have fun !

jQuery UI: Show dialog that user must confirm or cancel

I have a few links on my site that will need to show a modal dialog when the user clicks on one of them. The modal will contain a message like: You are now leaving the "SECTION NAME" part of "SITE NAME". The user will then either accept which will allow the user to continue on with their request or cancel which will keep the user where they are.
An example of a link would be: My Interests
So as you can see the class of leaving-section would cause the link to do what I have specified above, and will also open the link in a new tab/window BUT the user must first accept that they are aware they are being taken to another part of the site.
I have looked at the docs but I haven't seen any examples where a) the dialog is created on the fly rather than hiding and showing a div and b) allowing the user to confirm and being sent to their original location i.e. the url which they clicked.
This is what I have so far:
$("#leaving-section").dialog({
resizable: false,
modal: true,
buttons: {
"I understand, take me there": function () {
$(this).dialog("close");
},
"I want to stay where I am": function () {
$(this).dialog("close");
}
}
});
$('.leaving-section').click(function (event)
{
event.preventDefault();
var $dialog = $('#leaving-section');
$dialog.dialog('open');
});
But I want to the modal to be created by jquery instead of the div being embedded in the page! Also how do I get the first button to send them off to their original destination?
Thanks to all who can help. Thanks
I just had to solve the same problem. The key to getting this to work was that the dialog must be partially initialized in the click event handler for the link you want to use the confirmation functionality with (if you want to use this for more than one link). This is because the target URL for the link must be injected into the event handler for the confirmation button click. I used a CSS class to indicate which links should have the confirmation behavior.
Here's my solution, abstracted away to be suitable for an example.
<div id="dialog" title="Confirmation Required">
Are you sure about this?
</div>
<script type="text/javascript">
$(document).ready(function() {
$("#dialog").dialog({
autoOpen: false,
modal: true
});
});
$(".confirmLink").click(function(e) {
e.preventDefault();
var targetUrl = $(this).attr("href");
$("#dialog").dialog({
buttons : {
"Confirm" : function() {
window.location.href = targetUrl;
},
"Cancel" : function() {
$(this).dialog("close");
}
}
});
$("#dialog").dialog("open");
});
</script>
<a class="confirmLink" href="http://someLinkWhichRequiresConfirmation.com">Click here</a>
<a class="confirmLink" href="http://anotherSensitiveLink">Or, you could click here</a>
I believe that this would work for you, if you can generate your links with the CSS class (confirmLink, in my example).
I think this plugin may be help
http://jqueryui.com/demos/dialog/#modal-confirmation
Heres an example of how you can do it:
http://jsfiddle.net/yFkgR/3/
Or to do something besides cancel
http://jsfiddle.net/yFkgR/4/
You can just define your own buttons. You can style the dialog box anyway you want, i just used the default.
also to use ajax to load the html you can take a look at:
jQuery UI Dialog window loaded within AJAX style jQuery UI Tabs
There is an open option you can use to load html from a remote web page. I jquery you can create a div just be doing
$("<div>");
it will create the closing tag too. Or as suggested in the post you can also use
$('a.ajax')

Resources