Focus element loaded by jQuery $.get(...) - javascript

I'm loading a html snippet, insert it after a certain element and want to focus an input field with the class .focus. There could be more than one element with this class. Similar code with load(...) works.
var item = $(this).closest(".something");
$.get(
url,
function(data) {
item.after(data);
$(data).find(".focus").focus(); /* everything works except this line */
}
);
The relevant part of the loaded html:
<input type="text" class="focus" value="" name="email"/>
It looks like the element to be focussed is found (in the debugger), but it doesn't get the focus. Any idea what is wrong?

item.after(data) parses data into a set of DOM elements and puts them in your document.
$(data) then parses data into another set of DOM elements, which are never displayed.
You want
$(data).insertAfter(item).find(".focus").focus();

This is because data is not in the DOM.
Try this:
var item = $(this).closest(".something");
$.get(
url,
function(data) {
var $data = $(data);
item.after($data);
$data.find(".focus").focus(); /* everything works except this line */
//or you can do: $(".focus", $data).focus();
}
);

Try,
item.next().find(".focus").focus();

Try using item.next().find('.focus').focus(). In the Ajax callback, data isn't a jQuery object but a string of HTML; calling item.after() makes jQuery create DOM nodes from the HTML but they're not linked to your data variable.

That is because you are not calling focus() on the element which is added into the dom.
Try this.
var item = $(this).closest(".something");
$.get(
url,
function(data) {
item.after(data);
item.nextAll(".focus").focus(); /* everything works except this line */
}
);

Related

Serialising an HTML element that has event handlers

I am currently making a website for a class that I am in. It is supposed to be a store, made in Pure HTML, CSS, and JavaScript (no libraries including jQuery). I am currently attempting at making a functional cart right now. My idea is to take the element that has the information about that item (image and name, but price I kept to be constant throughout to make it simpler). From here, I thought about serialising that element and saving it to localStorage so that I can load it from the cart page. When I try JSON.serialize(product) where product is the element of the item, it only ends up with "{}" and nothing else. XMLS.serialiseToString() only gives the element without the event handler. How am I supposed to make this work?
I also tried loading the event handler in the cart page too, but I cannot figure out a way to get the HTML element from a string. Could someone tell me how to make this work? I looked at a few other questions on here but it does not make much sense to me.
Edit: I got the serialisation and deserialisation working using XMLSerializer. However, I want to change the click event handler after deserialising the element. How am I supposed to make this work?
XMLSerializer should work.
You will need to provide more code for what you're doing with local storage and your event handler but based on the info you provided, I included some code with comments below.
//this is a test click handler function to see if it still works after being added to page
function testClickHandler() {
console.log('I still work after being added to document again.')
}
//initialize XML serializer
var serializer = new XMLSerializer();
//get html element from document
var html = document.querySelector('#serializemecapt');
//convert element to string
var htmlString = serializer.serializeToString(html);
//once element is converted to string you can save in local storage
//after you retrieve the element again from local storage, use the code below to insert it into your document again
//insert element back onto page
document.body.insertAdjacentHTML('afterbegin', htmlString);
<div id="serializemecapt" onclick="testClickHandler()">Click me to see if the click event still works after I'm pushed back into the document.<br/><br/></div>
Edit: If you want to change the click handler after serialization, you can do something like this (run the snippet below and see comments):
//this function will be removed before serialization
function originalFunction() {
console.log('I am the original function before serialization.')
}
//this function will be added after serialization
function newFunction() {
console.log('I am the new function after serialization.')
}
//get html element from document
var html = document.querySelector('#serializeme');
//apply originalFunction to div using addEventListener
html.addEventListener('click', originalFunction)
//new function to demonstrate serialization
function serializeHtml() {
//initialize XML serializer
var serializer = new XMLSerializer();
//remove event listener for originalFunction before serialization
html.removeEventListener('click', originalFunction)
//serialize html
var htmlString = serializer.serializeToString(html);
//insert element back onto page
document.body.insertAdjacentHTML('afterbegin', htmlString);
//change innerText on element for example purposes
html.innerText = 'I am the same div as above after serialization. I have new text and a new function. Click me now and I will run the new function.'
//add newFunction to div using addEventListener
html.addEventListener('click', newFunction)
}
//get button element from document
var serialButton = document.querySelector('#serialButton');
//apply serializeHtml function to button using addEventListener
serialButton.addEventListener('click', serializeHtml)
<div id="serializeme"><b>Click me</b> before serializing to run the original function.<br/><br/></div>
<p><b>Click button below to serialize the div above and apply a new function to the div after serialization.</b></p>
<button id="serialButton">Serialize</button>

get the html of element itself using jquery .html()

How to get the html of element itself using Jquery html. In the below code I would like get the input element inside div using JQuery as shwon below
<div id="content">content div</div>
<input type='text' id="scheduledDate" class="datetime" />
$(function() {
console.log($('#scheduledDate').html('dsadasdasd'));
$('#content').html($('#scheduledDate').html());
});
EDIT:
Can I get the $("#scheduledDate") as string which represent the real html code of the input box, because my final requirement is I want to pass it to some other SubView( I am using backboneJS) and eventually use that html code in a dust file.
My original requirement was to get that input field as string so that I can pass it to some other function. I know, if I keep it inside a DIV or some other container, I can get the html by using .html method of JQuery. I dont want use some other for that purpose. I am just trying to get html content of the input box itself using it's id.
If you want to move the input element into div, try this:
$('#content').append($('#scheduledDate'));
If you want to copy the input element into div, try this:
$('#content').append($('#scheduledDate').clone());
Note: after move or copy element, the event listener may need be registered again.
$(function() {
var content = $('#content');
var scheduledDate = $('#scheduledDate');
content.empty();
content.append(scheduledDate.clone());
});
As the original author has stated that they explicitly want the html of the input:
$(function() {
var scheduledDate = $('#scheduledDate').clone();
var temporaryElement = $('<div></div>');
var scheduleDateAsString = temporaryElement.append(scheduledDate).html();
// do what you want with the html such as log it
console.log(scheduleDateAsString);
// or store it back into #content
$('#content').empty().append(scheduleDateAsString);
});
Is how I would implement this. See below for a working example:
https://jsfiddle.net/wzy168xy/2/
A plain or pure JavaScript method, can do better...
scheduledDate.outerHTML //HTML5
or calling by
document.getElementById("scheduledDate").outerHTML //HTML4.01 -FF.
should do/return the same, e.g.:
>> '<input id="scheduledDate" type="text" value="" calss="datetime">'
if this, is what you are asking for
fiddle
p.s.: what do you mean by "calss" ? :-)
This can be done the following ways:
1.Input box moved to the div and the div content remains along with the added input
$(document).ready(function() {
var $inputBox = $("#scheduledDate");
$("#content").append($inputBox);
});
2.The div is replaced with the copy of the input box(as nnn pointed out)
$(document).ready(function() {
var $inputBox = $("#scheduledDate");
var $clonedInputBox = $("#scheduledDate").clone();
$("#content").html($clonedInputBox);
});
Div is replaced by the original input box
$(document).ready(function() {
var $inputBox = $("#scheduledDate");
$("#content").html($inputBox);
});
https://jsfiddle.net/atg5m6ym/4485/
EDIT 1:
to get the input html as string inside the div itself use this
$("#scheduledDate").prop('outerHTML')
This will give the input objects html as string
Check this js fiddle and tell if this is what you need
https://jsfiddle.net/atg5m6ym/4496/

Problem using dynamically added html-object from javascript

I have a problem with dynamically including an object-tag in my html.
We have a external service which we call to get some html-fragment, it includes an object-tag, a script and a simple html-form. I take that content and add it to a div in my page and then try to execute the script that uses the included object. When i debug using Firebug I can see that the code is correctly inserted in the page but the script gets an error when it tries to access the object. It seems to me that the object isn’t initialized. Let me show you some code to exemplify what I mean.
getFragment makes an ajax call using jQuery to get the content.
var htmlSnippet = RequestModule.getFragment( dto );
$('#plugin').html( htmlSnippet ).hide();
The included content in plugin-div looks like this
<div id="plugin" style="display: none; ">
Browser:
Chrome
<object name="signer" id="signer" type="application/x-personal-signer2"></object>
<form method="POST" name="signerData" action="#success">
<input name="nonce" value="ASyhs..." type="hidden">
<input name="signature" value="" type="hidden">
<input name="encodedTbs" value="U2l..." type="hidden">
<input name="provider" value="nexus-personal_4X" type="hidden">
<input type="submit" onclick="doSign()" value="Sign">
</form>
</div>
The javascript that tries to use the “signer” object looks like this:
function doSign(){
var signer2 = document.getElementById("signer");
retVal = signer2.SetParam('TextToBeSigned', 'some value...');
... and then some more
}
It’s when i call the signer2.SetParam method that I get an error saying
Object #<an HTMLObjectElement> has no method 'SetParam'
But when I use the original page where the content is loaded when the page loads the script works so I know that the ‘SetParam’ method exists on the object and that the script works. But somehow it doesn’t work when I dynamically add it to the page afterwards.
I’ve Googled this a lot the last couple of days with no luck.
Does anyone have any idea on how to get this to work?
Best regards,
Henrik
First of all Object tag is not fully supported in all browsers (Source)
Next, from my experience, jQuery (which heavily relies on document.createDocumentFragment) sometimes fails to attach/trigger events on dynamically created/cloned DOM nodes, which could explain why your object failed to initialize.
That said, to try and fix your problem, I suggest using native document.createElement and document.appendChild methods instead of jQuery.html. You can try document.innerHTML but if that fails, you can always go with the ones I mentioned earlier.
My suggestion is to either alter your service to replace:
<script type="text/javascript">
function addElement(parentid, tag, attributes) {
var el = document.createElement(tag);
// Add attributes
if (typeof attributes != 'undefined') {
for (var a in attributes) {
el.setAttribute(a, attributes[a]);
}
}
// Append element to parent
document.getElementById(parentid).appendChild(el);
}
addElement('plugin', 'object', {name:"signer",id:"signer",type:"application/x-personal-signer2"});
</script>
OR if you cannot change the content that is returned by the service, run this after you include the content onto your page:
<script type="text/javascript">
/*
* Goes through al the object tags in the element with the containerid id
* and tries to re-create them using the DOM builtin methods
*/
function reattachObjectTags(containerid) {
jQuery('#'+containerid+' object').each(function(){
var attrs = {}, el = this;
// We're insterested in preserving all the attributes
var saved_attrs = {}, attr;
for(var i=0; i < el.attributes.length; i++) {
attr = el.attributes.item(i);
if(attr.specified) {
saved_attrs[attr.nodeName]=attr.nodeValue;
}
}
this.parentNode.removeChild(this);
var new_element = document.createElement('object');
for (var a in saved_attrs) {
new_element.setAttribute(a,saved_attrs[a]);
}
document.getElementById(containerid).appendChild(new_element);
});
}
// Do your stuff
var htmlSnippet = RequestModule.getFragment( dto );
$('#plugin').html( htmlSnippet ).hide();
// reattach all the object elements in #plugin
reattachObjectTags('plugin');
</script>
THIS IS ALL UNTESTED -
I typed this off the top of my mind, since I don't have the means to fire up IE and test this.
For a jQuery solution, I think this should work:
$("input:submit").click(function(){
$("#signer").append('<param name="TextToBeSigned" value="some value ...">');
... and then some more
});
Might want to give the submit button a class or an id and use that as a selector, if you have multiple forms on that page though.
Hope this helps.
I've set up a test script here: https://dl.dropbox.com/u/74874/test_scripts/object.html
If you open up Firebug/Web Inspector, you'll see that the SetParam method is in-fact, not defined. I don't know what it's supposed to do, but it's not defined in either case. If you're trying to add <param> tags to your embed, you could use the DOM API to do that. There is some code in the test script that does that, but I'll paste it here anyway:
var obj_signer = document.getElementById('signer');
var obj_p = document.createElement('param');
obj_p.id = "myp2";
obj_p.name = "TextToBeSigned";
obj_p.value = "some value ...";
obj_p.setAttribute('valueType', 'ref');
obj_signer.appendChild(e);
Or be faster using jQuery:
$("#signer").append("<param id='myp2' name='TextToBeSigned' value='some value ...' valueType='ref'></param>");

Parsing using mrss

I'm trying to parse an mrss feed using jquery but am having some difficulty targeting the child element.
Code:
$(xml).find("item").each(function(){
var $item = $(this);
alert($item.find("media\\:thumbnail").text();
});
MRSS Structure:
<media:thumbnail url="http://somewebsite.com/someimage.jpg" />
UPDATE
The solution $item.find("media\:thumbnail").attr("url") works very well in Firefox but running the code in Chrome reveals an undefined value. Can someone suggest a workaround.
Thanks
You're trying to display the text() of your found nodes. The example node you include has no text at all. You want the value of the url attribute:
$(xml).find("item").each(function(){
var $item = $(this);
alert($item.find("media\\:thumbnail").attr("url"));
});
If your media:thumbnail element had something between opening and closing tags you could use text() (and you still wouldn't be getting the url value):
<media:thumbnail url="http://somesite.com/simeimage.jpg">Some text string</media:thumbnail>

How can I replace a table with a new one using jQuery?

Whats the best way to replace a <table> with a new one using jQuery? I'm using ajax on the page to get the new data.
If you don't want to add a wrapper element, something like this should work:
$.ajax({
url: 'yoururl.php',
success: function(r) {
$('table#something').replaceWith(r);
}
});
..assuming the response you get is an table element.
Wrap it in a div, and:
$("#myDiv").load("/some/url.php"); // where url.php outputs the entire table
You can specify a portion of the remote document to insert by putting it's selector with the URL parameter as follows:
$("#myDiv").load("/some/url.php #myTable");

Categories

Resources