JQuery Mobile - Refreshing a Button After Changing It's Content - jquery-mobile

Is there a reason why the click handler is removed from my button after calling the button() method on it. I am changing the content of my buttons, and as a result I need to refresh them. I noticed refresh does not work, so I tried the button method.
This will restyle my "button", but I lose my click event.
How can I accomplish both?
http://jsfiddle.net/RQZG8/2/
And here is the code:
$("[data-role=button]").html("hello world").button();
$("[data-role=button]").click(function(){
alert("i have been clicked");
});
My big issue is that I have a div which is acting as a button. I want to change the content of the div, but I want to be able to have it continue to look like a button while keeping it's behavior.

Try this: $("[data-role=button] .ui-btn-text").html("hello world"); otherwise the padding is lost.

First of all IMHO, given your example that goes with the question (when you change only caption of a button), there is no much point to use a div as a button when jQM gives you a lot of standard choices.
All of these:
<button>Button element</button>
<input type="button" value="Button" />
<input type="submit" value="Submit Button" />
will be automatically enhanced by jQM to buttons without even specifying data-role="button".
And you can of course use a link as a button
Link button
Now if you still want to use your div as a button you don't need to specify data-role="button" just call button() plugin. That will create all necessary markup for you and your original div will be preserved as hidden.
<div id="button1">By button<div>
$("div#button1").button();
To refresh a button after you changed its caption you need to call refresh method:
$("div#button1").html("Hello World").button("refresh");
Now to normally handle the click event of a particular button (if it's not the only one on the page) you probably need more specific selector than just the data-role=button attribute. id would be perfect for that. So instead of
$("[data-role=button]").click(function(){...});
do
$("div#button1").click(function(){...});
And lastly you most certainly know that, but I didn't see it in your jsfiddle, so I just mention that you better put your code in one of the jQM page handlers. pageinit is recommended way to go.
$(document).on("pageinit", "#page1", function(){
...
});
Here is jsFiddle.

Related

Can I get a button in Shadow DOM to submit a form not in Shadow DOM?

I just ran into an interesting situation where I have a submit <button> inside the Shadow DOM of a native custom element that is placed inside a <form>.
<form id="one" action="" method="get">
<s-button>Select</s-button>
#shadow-root
<button>...</button>
<button>Outside</button>
</form>
I also have a <button> as a direct child of the <form>.
The child <button> causes the form to submit.
But the <button> in the shadow-root does not.
In a way I guess this makes sense. But has anyone figured out a way to tell the shadow-root <button> to work correctly with the <form> or is this something I will have to handle through JS?
I know click events are blocked at the Shadow DOM layer, but I am surprised that there is no way to allow the button to still be a part of the form, something that can be set up through an attribute or a property.
Sure I can capture the click event and then send a new one from this but that does not do the same thing since my event will no longer be user generated and there are a huge set of rules associated with that.
A button triggers a submit Event (on the FORM element)
Since Events can not pass the shadow DOM boundary (do not bubble up into the parent DOM)
I presume that is why a shadowDOM button (dispatching a submit event) is not received by the FORM element.
Requires Supersharps workaround with a hidden button in the light DOM (which then dispatches a submit event in the parent DOM)
Or (starting from light DOM) you find the (parent) FORM tag and dispatch a submit event yourself:
this.closest('FORM').dispatchEvent(new Event('submit'))
Follow the experts on shadowDOM and FORMs at: https://github.com/w3c/webcomponents/issues/187
customElements.define( 'my-button', class extends HTMLElement {
connectedCallback() {
this.attachShadow({mode:'open'}).innerHTML=`<button>Button In Shadow DOM</button>`
this.onclick = _ => this.closest('FORM').dispatchEvent(new Event('submit'))
}
})
<form onsubmit="return console.log('submit Event occured')">
<my-button></my-button>
<button>button in Document DOM</button>
</form>
Nested shadowDOMs
If the FORM is not a direct ancestor, you can find it with something like: How to reference to a method in parent component from child component with vanilla JS Web Components? (Not any framework or Library)
You'll have to handle it through Javascript anyway.
A simple solution is to add a (masked) <button> in the light DOM, and transfer the click event to it.
customElements.define( 's-button', class extends HTMLElement {
connectedCallback() {
this.attachShadow( {mode: 'open'})
.innerHTML = `<button>In Shadow</button>`
var submit = this.appendChild( document.createElement( 'button' ) )
this.onclick = () => submit.click()
}
} )
<form onsubmit="console.log('submitted');return false">
<s-button>Select</s-button>
<button>Outside</button>
</form>
Something else you can do that is not exactly a button in the ShadowDOM, is if your button[type=submit] has been slotted into the ShadowDOM. So if you have something like:
<some-component>
<button type="submit" slot="buttonSlot"></button>
</some-component>
That button can be used to trigger your form.
That button is in the light DOM but is easily handled from within your component via the slot. It will also retain all the appropriate keyboard, click, focus, etc. events without any trouble.
To minimize the light DOM html you don't even need it to be a type=submit you can set that from within your component and it will still be treated as the submit button for any parent form in the light DOM.
Bonus (or maybe trouble depending on how you look at it), it will retain the styling of other buttons on the page (unless you change that in your component).

Changing button data-theme dynamically in JQueryMobile

I'm having a little trouble dynamically changing a button's theme dynamically. From a different post I learned to use:
<input type="button" data-inline="true" data-mini="true" data-theme="c" id="my-button" value="Save">
<script>
$("#my-button").buttonMarkup({ theme: 'a' }).button('refresh');
</script>
Technically this works, until I mouse over - then the button falls back to data-theme "c". Is there a better way to dynamically change theme?
if you use a button as below
Save2
You can change the theme as below
$('#my-button2').attr("data-theme", "c").removeClass("ui-btn-up-e").addClass("ui-btn-up-c");
check out a live fiddle here http://jsfiddle.net/mayooresan/jfDLU/
I tried to find the answer for this one, but came up with this solution after looking into the DOM structure. I created the below function for toggling the theme on click the button. the hover class needs to be addressed only when changing the theme of the same button you are clicking.
These seems to work for input type button element. (jqm version 1.3.2)
function changeButtonTheme(buttonSelector,toTheme){
var currentTheme = $(buttonSelector).attr('data-theme');
var parent = $(buttonSelector).parent();
$(buttonSelector).attr("data-theme", toTheme).removeClass("ui-btn-up-"+currentTheme).addClass("ui-btn-up-"+toTheme);
parent.attr("data-theme", toTheme).removeClass("ui-btn-up-"+currentTheme).addClass("ui-btn-up-"+toTheme);
//parent.removeClass("ui-btn-hover-"+currentTheme).addClass("ui-btn-hover-"+toTheme);
}

Why isn't my submit button event not firing?

I'm creating a jQuery mobile form that will display a calculated answer in a div below the form. Basically, a client-side submit button However, i'm not really having luck trying to fire the event. But it seems to be reloading the page or DOM, I don't really know and adds the values from the selected items before the submit button was hit. It seemed like the form is being posted, when this form wasn't supposed to post anything. This form is taking values from the JSON file and add them as options, radio buttons and checkboxes. The code below does not seem to fire at all when the submit button is clicked:
$("form").submit(function(event){
alert("submit button clicked");
event.preventDefault(); // stop default behaviour of submit
event.stopPropagation(); //event handler moved to something else
calculate(); //invokes the calculate method
}
I'm not really sure on what attributes my form would need since this would be a client-side submit button. I only had the id and wrapped all the jQuery mobile controls inside the form.
The full site that I'm trying to get the submit event to work properly is here: http://goo.gl/C9tW7
UPDATE: Looks like I was missing the pound sign on the declaration of the event handler. It looks like this particular issue is resolved though. The submit button event handler is properly firing, but the calculations that needed to be displayed isn't executing the way it should.
from your code, you are missing ending parenthesis
$("form").submit(function(event){
alert("submit button clicked");
event.preventDefault(); // stop default behaviour of submit
event.stopPropagation(); //event handler moved to something else
calculate(); //invokes the calculate method
}); //<-- here
make sure your button's markup looks as below
<button data-theme="b" id="submit" type="submit">Submit</button>
and hoep you set your form id correctly

retain jquery-ui element classes after jquery .load()

I have a page on which I'm using jQuery UI Tabs, what I'm doing is loading the content of each tabs via Ajax, but the problem I'm having is that, in the content of my tabs, the buttons (I'm using jQuery ui button) lose all their jquery ui classes, meaning:
When the page loads for the first time, my buttons look like this:
<button class="my_button ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only">
<span class="ui-button-icon-primary ui-icon ui-icon-plusthick"></span>
</button>
As you can see, my buttons have all the jquery-ui classes ui-button, ui-widget, etc.... Also, my buttons have a span which displays a plus(+) sign as a label for my buttons. Therefore, my buttons display correctly.
But when I load the same content (which contains the same buttons) via Ajax, my buttons become like this:
<button class="my_button"></button>
As you can see, I lose all the jQuery ui classes of my button. Therefore, the button is not styled
How can I fix this?
NOTE : Please note that I did not manually add those jquery-ui classes to my buttons in my HTML. When you initialize the buttons using $(".my_button").button(); in jQuery, jQuery automatically applies all the necessary jquery-ui classes to my button appropriately. So please don't tell me it's because I didn't not assign the jquery-ui classes to my buttons upfront (I should not have to). Also, I tried .live(), .delegate(), none of those work.
Please help me with this anyone
Thank you
I've faced this problem once and solved this problem using the document.ready call like
function myreadyFunc(){
$(".my_button").button();
// Other codes
}
I had my document.ready like following
$(document).ready(function(){
myreadyFunc();
});
After each ajax (success) call I used to call
myreadyFunc();
Hope this will help you too. I used this approach to execute document.ready's code that was not possible by calling document.ready after each ajax call.

How do I prevent scrolling to the top of a page when popping up a jQuery UI Dialog?

I currently use jTemplates to create a rather large table on the client, each row has a button that will open a jQuery UI dialog. However, when I scroll down the page and click on one of those buttons, jQuery dialog will open, but the scroll position get lost and the page jumps back to the top (with the blocking and the actual dialog showing off the screen). Has anyone seen or know what might cause this problem?
Thanks.
Are you using an anchor tag to implement the "button" that pops the dialog? If so, you'll want the click handler that opens the dialog to return false so that the default action of the anchor tag isn't invoked. If you are using a button, you'd also need to make sure that it doesn't submit (by returning false from the handler) and completely refresh the page.
For example,
$('a.closeButton').click( function() {
$('#dialog').dialog('open');
return false;
});
<a class='closeButton'>Close</a>
If your buttons work with an html anchor tag with href="#" replace the href for example by href="javascript:;" or any other method that you use to disable the href. The reason why the scrolling happens is because of href="#" scrolls to the top of your page.
change your code like this
$('a.closeButton').click( function(e) {
e.preventDefault();
$('#dialog').dialog('open');
});
You can try :
scrollTo(0, jQuery("body"));

Resources