ajax replace content lose focus on text box - ajax

I don't even know if this is possible but here is an example:
<div id="register">
//bunch of markup including inputs
</div>
Via AJAX I replace the register div, but if there is a focus on a text box inside of the register div, it loses focus when replaces happens. Is there a way to maintain focus?
here is the javascript:
$("#cart_contents input").change(function()
{
$(this.form).ajaxSubmit({target: "#register_container", success: function()
{
}
});
});
I have lots of inputs inside this form, how can I figure out how to refocus

If you get an ID handle for the text box, e.g. textbox, when AJAX is complete, call:
$('#textbox').focus();
A more generic solution. Given focusable elements have IDs, bookend your AJAX stuff like so:
var focusedId = $(document.activeElement).attr('id');
// .. AJAX, replacement ..
$('#' + focusedId).focus();
Reference focus()jQuery, Using jQuery to test if an input has focus.

If you replace the markups inside the register div,the focus from earlier fields would be removed,use
$("#"+someid).focus();
to focus on the textfields with id if you are using jquery..

Related

Loading a hidden div into an AJAX jQuery UI tab (future DOM element)

I have been trying to manipulate content that is loaded into jQuery UI tabs via AJAX.
As you can imagine, these elements are "future" DOM elements and aren't manipulated by normal $(".someClass")functions.
I've read using .live() for event handling is now deprecated using jQuery 1.7+ and is replaced by the new .on() method.
My issue is that the div I want to hide, when it loads in an AJAX tab, must be manipulated after the initial DOM load and is not bound to a click event at first.
My functions, which are currently wrapped in $() are below.
I think I have the syntax correct for links that use a click handler, but I'm not sure of the correct way to ".hide()" my "hiddenStory" div at load.
I also think that the functions themselves shouldn't be wrapped in an overall $()?
Any help or advice would be greatly appreciated.
$(function(){
// this .hiddenStory div below is what I want to hide on AJAX load
// need syntax and/or new methods for writing this function
$(".hiddenStory").hide();
// this is a function that allows me to toggle a "read more/read less" area
// on the "hiddenStory" div
$(".showMoreOrLess").on('click', (function() {
if (this.className.indexOf('clicked') != -1 ) {
$(this).removeClass('clicked');
$(this).prev().slideUp(500);
$(this).html("Read More" + "<span class='moreUiIcon'></span>");
}
else {
$(this).addClass('clicked');
$(this).prev().slideDown(500);
$(this).html("See Less" + "<span class='lessUiIcon'></span>");
}
}));
});
// prevents default link behavior
// on BBQ history stated tab panes with
// "showMoreOrLess" links
$('.showMoreOrLess').click(function (event)
{
event.preventDefault();
// here you can also do all sort of things
});
// /prevents default behavior on "showMoreOrLess" links
Could you set the display: none via CSS and override it when you wanted to show the element's content? Another option, if you have to do it this way would be to add the `$(".hiddenStory").hide() in the callback from the AJAX load that is populating the element. For example:
$(".hiddenStory").load("http://myurl.com", function(){
$(".hiddenStory").hide();
}
);
If you aren't using the .load method, you should have some sort of call back to tie into (e.g. success if using $.ajax...)

Bookmarklet that adds a JavaScript function

I am currently trying to make a bookmarklet that adds, among other things, a DIV element to the page.
I'm doing this by adding the HTML code to body.innerHTML and that works fine. On this DIV element is a button that should allow to hide the added DIV. I therefore tried to add via JavaScript a JavaScript function to the innerHTML called function hideDiv().
The new JavaScript is added to the body and it looks fine. But it doesn't work.
Short example:
javascript:var b = document.body.InnerHTML; b=b+'<input type="button" onclick="javascript:alert("hello")"/>'; document.body.innerHTML = b;
This bookmarklet should add a button that shows an alert if its clicked. It adds the button but nothing happens when clicking on it.
Is this a general issue? Can JavaScript add (working) JavaScript to a page?
I think you should set an id and then just add the function to the element. Like this:
javascript:var b = document.body.InnerHTML; b=b+'<input type="button" id="test"/>'; document.body.innerHTML = b; document.getElementById('test').onclick = function () { alert('hi')}
The javascript: prefix is only used in href attributes (or action for forms). It is NOT used in onclick or any other events. Remove the javascript: and your code should work fine.

For a JQuery App with several buttons, should I use <input> buttons, <a> buttons, <button> buttons, or something else?

I need to create a jQuery App with 30 buttons, from 1 to 30, whereby each one calls the exact same action script via Ajax where the parameter that is passed to the action script is simply the number of the button pressed (1 to 30).
For example, let's say the action script is process.php, if button 3 is pressed, then I need to pull data from process.php?btn=3, and if button 27 is pressed, then I need to pull data from process.php?btn=27.
Which type of button should I use for this: <input> buttons, <a> buttons, <button> buttons, or something else? And why do you suggest that?
Also, how would Ajax get the corresponding value (1-30) of the button pressed with the method you suggest?
Thanks!
I would suggest to use <a/> that way if JavaScript is disabled you can maintain the application's functionality.
Button 3
And the script would simply use the href to post to your page.
$("a.actionButton").click(function(e){
e.preventDefault();
$.post(this.href, {}, function(data){
//do something with the data.
});
});
Update
Since JavaScript is required than my recommendation would depend on your application design. If you want the big buttons to look like buttons simply use <input type="button" value="3"/> As by default they will have hover effect, depressed effect built out of the box.
If your buttons do not look like normal buttons maybe just blocks or some other style a <div/> could also be an option. The one downside to using an <a/> would be you always have to suppress the default behavior of the click()
Each will work fine. But the <a> you can style with an image while <input> and <button> you cannot (the browser decides on the look).
Simply bind the click event on the button. Assuming you have this HTML:
Button 1
Button 2
...
Button 3
Here's the Javascript. The trick is to call the AJAX here, and return false to prevent the Browser from changing page.
$('a').click(function(e) {
$.get($(this).attr('href'), function(result) {
alert('AJAX result = '+result);
});
return false;
});
You could create a custom attribute on each button.
<input type="button" onclick="YourCallbackMethod(this)" buttonNumber="1" value="Button 1" />
In your javascript
function YourCallbackMethod(button)
{
var number = $(button).attr("buttonNumber");
// Call the ajax method with the number value.
}
By doing this you can add additional attributes to extend the data stored in each button and it also makes chaning the AJAX target link very easy since it's centralised, rather than spread around multiple anchor tags.
As an alternative to Marks answer, you could use a <form> element, and have each button a submit button; either a input or button. Set the name of the element to "btn" and the value of the element to the button number.
<form id="foo" action="process.php" method="<!-- POST or GET? -->">
<button type="submit" name="btn" value="1">Button 1</button>
</form>
The jQuery would look something like:
jQuery(document).ready(function ($) {
$('#foo').bind('submit', function (evt) {
jQuery.ajax({
url: this.action,
data: $(this).serialize(),
success: function () {
// whatever
}
});
evt.preventDefault();
});
});
If you want the submission to be a POST request, this would most likely be better. For a GET request however, Marks will probably be easier.

Browser Memory Usage Comparison: inline onClick vs. using JQuery .bind()

I have ~400 elements on a page that have click events tied to them (4 different types of buttons with 100 instances of each, each type's click events performing the same function but with different parameters).
I need to minimize any impacts on performance that this may have. What kind of performance hit am I taking (memory etc) by binding click events to each of these individually (using JQuery's bind())? Would it be more efficient to have an inline onclick calling the function on each button instead?
Edit for clarification :):
I actually have a table (generated using JQGrid) and each row has data columns followed by 4 icon 'button' columns- delete & three other business functions that make AJAX calls back to the server:
|id|description|__more data_|_X__|_+__|____|____|
-------------------------------------------------
| 1|___data____|____data____|icon|icon|icon|icon|
| 2|___data____|____data____|icon|icon|icon|icon|
| 3|___data____|____data____|icon|icon|icon|icon|
| 4|___data____|____data____|icon|icon|icon|icon|
I am using JQGrid's custom formatter (http://www.trirand.com/jqgridwsiki/doku.php?id=wiki:custom_formatter) to build the icon 'buttons' in each row (I cannot retrieve button HTML from server).
It is here in my custom formatter function that I can easily just build the icon HTML and code in an inline onclick calling the appropriate functions with the appropriate parameters (data from other columns in that row). I use the data in the row columns as parameters for my functions.
function removeFormatter(cellvalue, options, rowObject) {
return "<img src='img/favoritesAdd.gif' onclick='remove(\"" + options.rowId + "\")' title='Remove' style='cursor:pointer' />";
}
So, I can think of two options:
1) inline onclick as I explained above
--or--
2) delegate() (as mentioned in below answers (thank you so much!))
Build the icon image (each icon type has its own class name) using the custom formatter.Set the icon's data() to its parameters in the afterInsertRow JQGrid event. Apply the delegate() handler to buttons of specific classes (as #KenRedler said below)
> $('#container').delegate('.your_buttons','click',function(e){
> e.preventDefault();
> var your_param = $(this).data('something'); // store your params in data, perhaps
> do_something_with( your_param );
> }); //(code snippet via #KenRedler)
I'm not sure how browser-intensive option #2 is I guess...but I do like keeping the Javascript away from my DOM elements :)
Because you need not only a general solution with some container objects, but the solution for jqGrid I can suggest you one more way.
The problem is that jqGrid make already some onClick bindings. So you will not spend more resources if you just use existing in jqGrid event handler. Two event handler can be useful for you: onCellSelect and beforeSelectRow. To have mostly close behavior to what you currently have I suggest you to use beforeSelectRow event. It's advantage is that if the user will click on one from your custom buttons the row selection can stay unchanged. With the onCellSelect the row will be first selected and then the onCellSelect event handler called.
You can define the columns with buttons like following
{ name: 'add', width: 18, sortable: false, search: false,
formatter:function(){
return "<span class='ui-icon ui-icon-plus'></span>"
}}
In the code above I do use custom formatter of jqGrid, but without any event binding. The code of
beforeSelectRow: function (rowid, e) {
var iCol = $.jgrid.getCellIndex(e.target);
if (iCol >= firstButtonColumnIndex) {
alert("rowid="+rowid+"\nButton name: "+buttonNames[iCol]);
}
// prevent row selection if one click on the button
return (iCol >= firstButtonColumnIndex)? false: true;
}
where firstButtonColumnIndex = 8 and buttonNames = {8:'Add',9:'Edit',10:'Remove',11:'Details'}. In your code you can replace the alert to the corresponding function call.
If you want select the row always on the button click you can simplify the code till the following
onCellSelect: function (rowid,iCol/*,cellcontent,e*/) {
if (iCol >= firstButtonColumnIndex) {
alert("rowid="+rowid+"\nButton name: "+buttonNames[iCol]);
}
}
In the way you use one existing click event handler bound to the whole table (see the source code) and just say jqGrid which handle you want to use.
I recommend you additionally always use gridview:true which speed up the building of jqGrid, but which can not be used if you use afterInsertRow function which you considered to use as an option.
You can see the demo here.
UPDATED: One more option which you have is to use formatter:'actions' see the demo prepared for the answer. If you look at the code of the 'actions' formatter is work mostly like your current code if you look at it from the event binding side.
UPDATED 2: The updated version of the code you can see here.
You should use the .delegate() method to bind a single click handler for all elements ,through jQuery, to a parent element of all buttons.
For the different parameters you could use data- attributes to each element, and retrieve them with the .data() method.
Have you considered using delegate()? You'd have one handler on a container element rather than hundreds. Something like this:
$('#container').delegate('.your_buttons','click',function(e){
e.preventDefault();
var your_param = $(this).data('something'); // store your params in data, perhaps
do_something_with( your_param );
});
Assuming a general layout like this:
<div id="container">
<!--- stuff here --->
<a class="your_buttons" href="#" data-something="foo">Alpha</a>
<a class="your_buttons" href="#" data-something="bar">Beta</a>
<a class="your_buttons" href="#" data-something="baz">Gamma</a>
<a class="something-else" href="#" data-something="baz">Omega</a>
<!--- hundreds more --->
</div>

Loading the target of a link in a <DIV> via jQuery's .live event into the same <DIV>?

I call a certain div from another page with jquery to be loaded into a div on my main page like this:
<script type="text/javascript">
$("#scotland").load("http://www.example.com/scotland .gallery");
</script>
<div id="scotland"></div>
The div I call is a piece of code which is automatically generated by a CMS made simple module, by the way.
Now it comes to my problem: The .gallery div I call, looks, a little simplified, like this:
<div class="gallery">
<span><img src="http://www.example.com/scotlandimage1.jpg"></span>
<span class="imgnavi"><a href="link_to_next_page_with_one_image">Next image</href></span>
</div>
I want the "next image"-link to load the next page into the .gallery div (it is always a page with one image on it). But what it does, is, it opens the new page http://www.example.com/scotland only.
I tried to use jquerys .live event to load the linked page (that would be "scotlandimage2" and the navigation, as you can see in the upper part - not only the image!), but I must have done something wrong. I tried different ways, but never got it to work. This was my last try:
$(".imgnavi a").click(function() {
var myUrl = $(this).attr("href");
$(".gallery").load(myUrl);
return false;
});
I have to admit that I am very new to jquery... But does someone know what I did wrong (do I even follow the right handlers?)?
Thanks very much in advance!
Martin
Your first attempt is good, but you're missing the required-for-ajax call to live instead of click:
$('.imgnavi a').live('click', function(ev) {
// Stop regular handling of "click" in most non-IE browsers
ev.preventDefault();
ev.stopPropagation();
// Load the new content into the div (same code you had)
$('.gallery').load($(this).attr('href'));
// Stop regular handling of "click" in IE (and some others)
return false;
}
EDIT in response to the question: "What will happen with the old $('gallery') content?"
With the above code, the old content will be replaced with the response to the .load() request. If you want to, say, prepend the image instead, you can just wrap the .load() call in a call to the built-in jQuery $.prepend( content ) method, like so:
$('gallery').prepend($.load($(this).attr('href')));
The same works for appending.

Resources