ajax loading of search results - javascript

I have setup a search funtionality that will search in an XSLT file. This works flawlessly but I have a little trouble returning the search results dynamically with ajax.
This is my JS:
var SearchHandler = function(frm) {
frm = $(frm);
var data = frm.find(".search-field").val();
$.ajax({
method: 'GET',
url: '/',
data: { query: data },
dataType: 'xml',
success: SearchSuccessHandler,
error: SearchSuccessHandler
});
};
var SearchSuccessHandler = function(html) {
};
What I want is the SearchSuccessHandler to dynamically load the search result from index.php?query=searchword
I just can't seem to figure out the right way to handle it.

Based on your comment:
Bah.. Sorry... The ajax call will return some new html based on the
query ... I want the existing html to be replaced I have tried
$('body').html(html.responseText); but then I cannot search again
because javascript is not loaded correctly
It's not the AJAX which is the issue but rather event delegation
When you bind a function to an element directly like this:
$('.my-element').on('whatever', function() { ... })
the handler will work as long as the element exists however if you replace the contents of the entire body you'll run into trouble as your original .my-element no longer exists.
You can overcome that by using event delegation to make sure your function keeps searching e.g.
$(body).on('whatever', '.my-element', function() { ... })
This basically says: "If I click on body and the target is .my-element then execute this function"
Instead of a directly bound handler which says: "If I click on this specific element then execute this function"
the body will always exist and therefore you'll always be able to delegate down from the body but if you can do it on some more specific element that would obviously be better since then you won't have an onclick handler on the entire body.
I think this is what your issue is since you're replacing the entire body.

Try this
success:function(data) {
// do your stuff here
}
Of course, you need to be sure your function is returning some values.
To make it easier for your, encode the values as json on your index.php
return json_encode($values)
Then, inside your success function, just parse it with eval()

Related

Javascript does not work on returned ajax results

I have an ajax call that returns html. This works well on changes. What does not work though is the javascript I have that does stuff based on clicks in the returned results.
The ajax call is:
function update_order_shipping(){
$.ajax({
url: 'ajax_order_shipping.php',
method: "post",
dataType: 'html',
success: function (result) {
$('#shipping-method').html(result);
},
error: function(xhr, status, error) {
//alert(xhr.responseText);
}
});
};
This works well. Returns the exact results I need.
The issue is that these returned results also have radio buttons and on change I perform this javascript:
$('input[name="shipping"]').change(function() {
if($(this).is(':checked') && ( $(this).val() == 'freeamount_freeamount' ) ){
document.getElementById('fedex_number').style.display="none";
document.getElementById('ups_number').style.display="none";
document.getElementById('your_shipping_conditions').style.display="none";
var shipping_method = document.getElementById('text-freeamount').innerText;
document.getElementById('text-shipping').innerHTML = shipping_method;
var shipping_value = document.getElementById('value-freeamount').innerText;
document.getElementById('value-shipping').innerHTML = shipping_value;
}
});
Now on initial page load this works great, but the returned results which is identical html as the intial page load, the javascript fails to work. I understand it has to do with binding or something like that, but not quite sure how to implement it, so that results will always use the javascipt.
You need to use on to bind events to dynamically created elements.
$("body").on("change", "input[name='shipping']", function(event) {
// stuff here
});
"body" can be replaced with any non-dynamic element that's an ancestor of your input.
Any matching events will automatically listen for the change event, whether the element was added at the start or later.

Call method when dynamic element is in DOM

I use $http service to get data and generate DOM elements.
How can I in jQuery/AngularJS call a method (example .slideToggle()) on dynamic element? I need to do this when page is loaded (not on click event etc.).
To do this one $('#test').slideToggle() (#test is generated element) i need use timeout.
It's difficult to know for sure from your description, but if you're creating the element from data you retrieve remotely, you should ensure that element's creation/insertion are completed before you attempt to scroll to it.
The following code is an example of how you may do this:
$http({
method: 'GET',
url: '/someUrl'
})
.then(createAndInsertYourElement)
.then(scrollToElem);
function createAndInsertYourElement(data) {
var $elem = $('<div id="test">' + data.whateva + '</div>');
$('#someElement').append($elem);
return $elem;
}
function scrollToElem($elem) {
$elem.slideToggle();
}
Note the .thens. These are an option because Angular's $http returns a promise. If you're not familiar with promises, yet, they are awesome, and you should check 'em out: http://www.dwmkerr.com/promises-in-angularjs-the-definitive-guide/

Setting the innerHTML of an anchor tag through JavaScript

I have an anchor tag on an ASP.NET page, whose text (inner HTML) I wish to populate, through JavaScript, with an integer retrieved from a Web Service.
I tried this using the following:
HTML:
<script type="text/javascript">
$(function () {
GetEntityCount([{ domId: document.getElementById("entityCountIndicator")}]);
});
</script>
<a id="entityCountIndicator"></a>
JavaScript:
function GetEntityCount(domId) {
$.ajax({
type: 'POST',
url: webServiceProxy + '/GetEntityCount',
cache: true,
success: function (xml) { GotEntityCount($(xml).text(), domId); }
});
}
function GotEntityCount(entityCount, domElement) {
if (isNaN(entityCount)) return;
domElement.innerHTML = entityCount.toString();
}
but it did not work.
After examining the variables in FireBug, and doing a bit of experimentation I managed to get it working by changing the line that sets the innerHTML to:
domElement[0].domId.innerHTML = entityCount.toString();
This seemed to do the trick, but I have no idea why it is working or what is happening here.
Why is the document.getElementById("entityCountIndicator") call apparently returning an array, rather than a single element? And why do I then have to probe the first element of that array and set innerHTML on its domId property?
Because your are passing an array in
[{ domId: document.getElementById("entityCountIndicator")}]
Your code can't possibly work, as:
Your passing an array as your first argument (GetEntityCount([{ domId: document.getElementById("entityCountIndicator")}]);), but next try to write the innerHTML from the second element (domElement)
Why are you passing an object inside an array as your domElement, rather than only the element like this: GetEntityCount(0,document.getElementById("entityCountIndicator"));
And here you seem to only pass an id, rather than a dom element: GotEntityCount($(xml).text(), domId);
Edit: I guess I took too long to answer, nevermind in that case.

Trying to understand why AJAX objects added into DOM return undefined

I have a problem when calling a ajax call that after the ajax data is appended into the DOM, any Javascript referring to the appended html returns that the object is undefined.
The forms use tags with Javascript submits and some Javascript to modify hidden fields, thats why the eval() is in there.
edit: This is an example of a 'href' tag and why I have the eval in there:
javascript:document.faultList.sortBy.value='4';document.faultList.sortByPrev.value='3';document.faultList.Action01.value='SetMyRequestItem';
Its how the previous developer has created this software/website before my time instead of using a REST style system.
This is my code:
function ajaxFormUpdate(formID,linkClass){
$(formID+' '+linkClass).click(function(){
eval($(this).attr('href'));
serialised = $(this).closest(formID).serialize();
$.ajax({
type: "POST",
url: 'jadehttp.dll?EbdMulti_www_01',
data: serialised,
success: function(data) {
//console.log(data)
$(formID).html($(data).find(formID));
loadHandlers();
}
});
return false
});
}
function loadHandlers(){
ajaxFormUpdate('#faultList','.ajaxLink');
ajaxFormUpdate('#accessCardList','.ajaxLink');
ajaxFormUpdate('#facilityList','.ajaxLink');
ajaxFormUpdate('#carParkingList','.ajaxLink');
ajaxFormUpdate('#visitorList','.ajaxLink');
}
loadHandlers();
Resolved this by changing .html() to .replaceWith() (thanks jgauffin for putting me on the right track) and using the following click handler instead of the standard .click()
$(".selector_class").live('click', function() { alert("new element clicked"); });

Prototype Event.observe not seeing AJAX-returned HTML

I'm trying to create a CMS system based on AJAX using Prototype's library. On a page load, I have HTML, page title and additional Javascript for the page returned via JSON, and I update the HTML on the main area. I also have an event listener that listens for certain ID's to be clicked on.
The listener is working,
var TabMenu = {
selectedTab: 'main',
showTab: function(pid) { alert(pid); alert($(pid));
$(pid).addClassName('selected'); this.selectedTab = pid;
$(this.defaultTab).removeClassName('selected');
}};
After loading, I click on one of the new tabs, and the first "test" alert successfully alerts the element's ID, but the second alert ($(pid)) returns null. I can only surmise that the HTML returned by the AJAX request is not being evaluated and added to the DOM, otherwise it would alert [HTMLDivElement] instead of "null".
Here is the relevant AJAX call:
new Ajax.Request(url, {
onSuccess: function(t) {
data = t.responseText.evalJSON();
Page.update(data.html, data.title, data.js);
Page.destroyLoader();
}
});
And here is the updating function:
update: function(data, title, js) {
document.title = Global.title + title;
if (title != "") { $('HEADING').update(title); }
$('MAIN').update(data);
if (js != "") {
var nuJS = new Element('script', { type: 'text/javascript' }).update(js);
$('MAIN').insert({ top: nuJS });
}
}
Any ideas on how I can get this working?
When is the ajax request triggered? Is it triggered when you click the tab? If so the showTab function is being triggered before data has been inserted into the DOM.
If you have firebug, try using the console to select the html data, after the ajax call has finished, to see what you get. You can also use firebug's html tab to see if the data has been inserted into the DOM.
Also, even though you get the pid parameter that is set to a value, does it refer to a real id that exists in the DOM?
From your code and the comment above.
I think your plan is to load all the tabs after the page loaded immediately.
And hide all of them using the css. Wait until the user click the tab,
Show only the one that is "selected", right?
That's mean you should change:
$('MAIN').update(data);
To something like
$('MAIN').update({after: data});
So it won't overwrite the existed one.
And don't forget to move the code for document.title and eval js into showTab function.
For javascript evaluation you can insert the js into data.html and use this instead:
$('MAIN').innerHTML.evalScripts();

Categories