jQuery buttonset: intercept clicks so that buttons don't change state - jquery-ui

I am using jQuery UI buttonset for an on/off pair of buttons, mainly because of the nice styling you get with it. I want to handle clicks so that when you click one of the two buttons you get a dialog where you can make some more choices, and after that the page reloads with the buttons in their new state (if the state was changed, which may not be the case).
The problem is that the button that you click gets styled as selected before any click handlers are called, it seems. I don't want the selection to change, I want to do that manually.
It seems that the click event is bound to the label that jQuery UI creates, and I'm struggling a bit with unbinding it. I guess I'm also asking if there is some other way to get the style without the function... since buttonset doesn't offer any event handlers I need to catch the click events myself anyway.
The solution I'm thinking of right now is simply copying the html that buttonset generates into my code, keep the css and remove the buttonset call. I thought it might worth it to check on StackOverflow before giving up though. :)

Since jQuery UI doesn't trigger any events that run before for the actual selection is made the workarounds to accomplish this are going to be relatively hacky. The best idea I could come up with is to programmatically remember the previously selected option and then attach a click handler that determines whether you should revert jQuery UI's selection of the new button or not.
$('#parent_container').buttonset();
var selectedButton = $('#parent_container :checked');
$('.ui-button').on('click', function() {
setTimeout(function() {
//Insert your actual check here.
if (true) {
selectedButton.attr('checked', true);
$('#radio').buttonset('refresh');
} else {
selectedButton = $('#parent_container :checked');
}
}, 1);
});​
The setTimeout is necessary to ensure that this runs after jQuery UI's click handler. Since you're showing a dialog you might need to alter this to instantly revert the selection, but remember what the user attempted to select for future use.
I have an example of always refusing the user's selection here - http://jsfiddle.net/tj_vantoll/s6XTu/14/
Obviously this is not an ideal approach but it does work. jQuery UI should really add support for selection events; I'll try to get around to filing a ticket for this. The button plugin is due for some updates in 1.11 - http://wiki.jqueryui.com/w/page/12138038/Roadmap.

Related

What jQuery Mobile event is best for

I am developing a jQuery Mobile application that will run into a Cordova wrapper.
I am struggling to understand the use of each pagecontainerX event and when to use which.
I will post three specific use cases:
1) hook click events:
Say I want to assign a handler to a certain click event on a button.
2) change textual content of the page:
Say I have a page and I want to update some content that might have changed since last time I have shown the page.
3) change graphical content of the page:
Like if I want to draw on some canvas, or in cases where I need to know how things are rendered and their size.
Preliminary answers:
these is what I have found myself, but I would really much appreciate comments:
1) I am using the pagecreate event, as it's only called once. It is also possible to specify what specific page you want to hook the handler to by doing: $(document).on("pagecreate", "#pageid", handler);
2) I am using pagecontainerbeforetransition or pagecontainerbeforehide. Pagecontainerbeforehide has the advantage that is only fired once, while the other is fired twice (dunno why). Other options, like pagecontainershow, will change the content after transition, which is a bit weird to look at.
3) In this case I am employing pagecontainershow, so that things have already been graphically rendered and I can compute heights and widths etc., the drawback is that the user will see the transition, and only after he will see the content of the page being modified.

Select2 additional checkbox not checking

Hei guys.
I'm trying to add additional HTML elements below search box.. like checkboxes for filtering purposes.
But the added checkbox is not functional, you can't actually check it. I'm not sure but I think that search box is taking the focus from them... I created this jsFiddle so you guys can check it out.
http://jsfiddle.net/6wz2hLh0/
$("#e1").select2();
//Inserting additional HTML elements below search... filter in my case
$(".select2-search").after("<input type='checkbox'/>");
When the dropdown is open you can't even write in jsFiddle input's.
I tried commenting out various focus calls from source code with no luck.
Can any one point me in to right direction in source code what is causing this non stop search box focussing.
One thing to try is to have the checkbox element stop the mouse events from propagating. That seems to prevent them from getting to Select2, so Select2 cannot kill them.
$("<input type='checkbox'/>")
.insertAfter(".select2-search")
.on('mousedown mouseup click', function(e) { e.stopPropagation(); });
jsfiddle
I'm not sure but I think that search box is taking the focus from them
My guess is that this is because Select2 kills (stops propagation and prevents default) most events that occur within the dropdown. This is so Select2 doesn't leak events, but it also causes problems like not being able to catch click events or embed links.
When the dropdown is open you can't even write in jsFiddle input's.
This is because Select2 uses a mask that captures all events outside of the dropdown.
Can any one point me in to right direction in source code what is causing this non stop search box focussing.
You are going to want to look through the source for killEvent, as this is the method Select2 uses that kills events. As most browsers listen for the click event for native controls, you probably want to remove this killEvent for dropdown clicks.

jQuery Mobile Fast Radio Buttons

Another topic on the much discussed issue of button responsiveness when web apps are used on mobile devices.
I am listening for the touchend event to trigger a radio button being pressed. This solves the issue of making the button more responsive, however creates another problem.
jQuery mobile applies classes such as ui-icon-radio-on, ui-radio-on, ui-btn-hvr-a, ui-btn-dwn-a when the event occurs that get left behind. This makes the button look like it is still being pressed even though the event is over. It ends up being a decent effort to juggle removing and adding all those classes to make everything look right.
My questions is - does anyone have an elegant way of adding and removing the needed classes and attributes.
or
Is there a better way of going about this that will not involve "recreating the wheel" in terms of manually dealing with the styling based on event triggers. Would google's fast button be a better solution? (not sure how to integrate). Is there a simpler way?
$(document).on('pageinit pageshow', 'div:jqmData(role="page"), div:jqmData(role="dialog")', function (event) {
if($(this).hasClass('AdminSurv') && event.type=='pageinit') {
$(this).on( 'touchend', '.ui-radio', function(event) {
event.preventDefault();
/*uncheck all radios in control group to avoid multiple checks*/
var _control_group = $(this).parent();
_control_group.find("input:radio:checked").attr('checked',false);
/*check the radio*/
$(this).find('input').attr('checked', true);
/*much juggling of classes/attributes going on here
still looks like the buttons are being held down
this is a very sloppy example of my initial attempt*/
_control_group.find('label').removeClass('ui-radio-on');
_control_group.find('label').removeAttr('data-icon');
_control_group.find('label span span').removeClass('ui-icon-radio-on');
$(this).find('label').removeClass('ui-radio-off');
$(this).find('label').addClass('ui-radio-on');
$(this).find('label').attr('data-icon','radio-on');
$(this).find('label span span').removeClass('ui-icon-radio-off');
$(this).find('label span span').addClass('ui-icon-radio-on');
});
}
});
Many jQuery Mobile widgets accept refresh method, in which it is used to enhance markup of elements already existing in DOM or are inserted dynamically.
For checkbox and Radio buttons, .checkboxradio('refresh') combined with .prop() are used to enhance/modify the markup by adding/removing classes, for checked and unchecked elements dynamically.
Check
$('.selector').prop('checked', true).checkboxradio('refresh');
Uncheck
$('.selector').prop('checked', false).checkboxradio('refresh');
Demo
Reference: Checkboxradio Widget

JQM back button binds itself to every click event when it isn't targeted

Using jQuery Mobile (jquery.mobile-1.0b3.min.js). If i apply a click event to a form, the back button seems to get the click event binding as well. It does this no matter how specifically targeted to an element the selector is. For example:
Using this to set the back button:
Copy code
<div id="pagename-page" data-role="page" data-add-back-btn="true" data-back-btn-theme="b">
And this in a script file:
Copy code
$('#awards-details-page').live('pagecreate', function(event){
$('#awards-details-page input[name=submit]').bind('vclick', function() {
console.log('I'm going to be hijacked by the back button.');
});
});
Clicking on the back button will produce the message in the console when tested in a browser.
Every time you visit the page with the script, it will add another duplicate binding. Attempts to unbind the click event on the pagehide event worked with the targeted element, but back button's bindings persisted.
Can anyone shed some light on this?
Thank you in advance.
dont use vclick you will ge ghost, they have improved CLICK so just use that
also live is not bind... bind is to an element that exist, live is for all elements that have that shared property, before after and during. you past pages exist so you have a set of binded items now not just one for the page you are on. i would scrap the whole back button element and have your own clickable item, for this you can do your own back code and add attributes like data-backto = "#page1", you can then control better what happens when a back button is clicked, especially as android phones have there own back button too.

Do touch events not work with text-input elements in iPad Safari?

In iPad Safari, I have programmed a DIV's touch-events so that when you touch inside the DIV and hold your finger there for 500 ms, the DIV's background color changes.
When I try to move the code over to a text-input element (inside a fieldset), making it the touch-target instead of the DIV, the code doesn't work. The text-input becomes selected in spite of this CSS:
input[type=text] {-webkit-touch-callout:none; -webkit-user-select:none }
Is there no way to intercept the touch events of a text-input element in iPad Safari and handle them in a custom manner, preventing default behavior? Or is there something additional that I must do to get the input to support this? I've tried with and without a dummy click handler: onclick="void(0)".
This is the doc I'm following the documentation Handling Events.
It would be helpful if you posted your code, but I'm thinking you probably just need to prevent the default behavior on touch events. This looks something like this if using jQuery:
$("#ID")
.bind("touchstart",
function (e) {
e.preventDefault();
//do something
})
.bind("touchmove",
function (e) {
if (e.preventDefault) {
e.preventDefault();
}
//do something
});
If you don't call preventDefault() in your handler code, the browser will automatically pass the touch event through to the default implementation (after you think you've handled it). The default implementation is to select the field.
So, in your case, call preventDefault() and stopPropagation() in your handler, and return false. This prevents the event from bubbling further. Then you can totally control your input element.
Caveat: You'll then also lose the default behavior of the input field! In other words, you'll not be able to input text into the field! Or if the input field is a <select>, you won't be able to pull up the list etc.
I suppose what you really want is: 1) If user presses and hold for 500ms, then turn yellow, 2) and/or on release activate the input field. In that case, you'll have to manually refire the event upwards when you really want to use the input field.
This kind of situation is very common when programming the iPad. For example, in many cases you'd want to detect a touch-drag motion (even on an input field) and interpret it as a move, but interpret a touch-release motion (without moving) as a click to activate the input field. You have to do what I suggest above: preventDefault() and refire event when necessary.
Try to disable and make your input readonly:
<input type="text" readonly />

Resources