JQGRID: Trigger Reload not working on iFrame - javascript

I have a web page with an iFrame. It loads a web page (same domain) with a jqGrid table. What I'm trying to do now is:
You press a link called search it opens a dialog with a filter form to filter your search.
When you press search button inside the dialog, it changes jqGrid url param and it should .trigger('reloadGrid').
It does all except the reloadGrid, I don't know why.
Any suggestion?
Code:
// DIALOG-ACTION-SEARCH IS THE BUTTON CLASS
$('#dialog').find('.dialog-action-search').button({icons: {
primary: 'ui-icon-search'
}, text: true}).click(function(e) {
e.preventDefault();
$('.content-center').contents().find('#list').setGridParam({
url: 'filteredsearch.html?option=1'
}).trigger('reloadGrid');
$('#dialog').dialog('destroy');
$('#dialog').remove();
});

setGridParam returns a jqGrid object, not a jQuery object, so I'm pretty sure you can't chain the trigger method. Try this instead:
var list = $('.content-center').contents().find('#list')
list.setGridParam({
url: 'filteredsearch.html?option=1'
})
list.trigger('reloadGrid');

I've found that before calling trigger('reloadGrid') with JSON data, you should reset the datatype parameter.
$("#grid").jqGrid('setGridParam', { datatype: 'json' });
In response to your comments, I would split up the chained method calls and then put a breakpoint on e.preventDefault() in Chrome debugger so you can assure that everything is actually getting hit.
$('#dialog').find('.dialog-action-search').button(
{
icons: { primary: 'ui-icon-search' } ,
text: true
});
$('#dialog').find('.dialog-action-search').click(function(e) {
e.preventDefault();
var grid = $('.content-center').contents().find('#list');
$(grid).jqGrid('setGridParam', { url: 'filteredsearch.html?option=1' });
$(grid).jqGrid('setGridParam', { datatype: 'json' });
$(grid).trigger('reloadGrid');
$("#dialog").dialog('destroy');
$("#dialog").remove();
});
While I'm a fan of chaining when you can, in this case I don't think you're going to find the root of the issues without doing things a little more explicitly, especially when using .find. How do you know that the .find is actually returning the element that you want?

I experienced same problem. I did not have time to investigate why it was happening but found a workaround for it.
In a javascript file that loads inside iframe with your grid I declared
window.top.reloadEventList = function () {
$("#grid").trigger("reloadGrid");};
Then just call
window.top.reloadEventList()
instead of
list.trigger('reloadGrid')

Related

Bootstrap modal does not work correctly with my ajax code

I created a partial view called ModalReq, which needs to be populated with data from the database.
The controller and view is working correctly.
But when you click on an element with the class '.car-box', nothing happens at first, after the second press, the correctly filled modal appears, but it doesn’t want to close in any way, how to make the modal work correctly?
Ajax code in main view:
<script>
function ajaxReq(url,type,selector) {
$.ajax({
url: url,
type: type,
contentType: 'application/json',
success: function (data) {
$(selector).html(data);
}
});
}
</script>
<script>
$(document).on('click', '.car-box', function () {
var objText = $(this).children('.box-his').children("span").text();
var objId = objText.substring(1, objText.length);
ajaxReq("#Url.Action("ModalReq")" + "?productId=" + objId, "POST", '#result');
$('#myModal').modal('show')
});
</script>
And I create a div with it at the very bottom of this view( but still above the Ajax code )
<div id="result"></div>
When you click on an element with the class '.car-box', the Ajax code creates an object that receives its number with a string type inside the card. It then leaves only a number with the same type of string. Then I call ajaxReq in which I transmit my partial view that accepts the Id specified by us. Then includes the created modal ...
I never use ajax before, so I need your help =)
In the current iteration $('#myModal').modal('show') is not waiting for the Ajax response.
How about moving it to your success function?
success: function (data) {
$(selector).html(data);
$('#myModal').modal('show')
}
Then the modal will get the data after one press.
Or: this answer jQuery ajax with ES6 Promises should give you guidance setting it up as a Promise.

ajax loading of search results

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()

Set bootstrap tooltip to AJAX call results

I have a bootstrap tooltip that I want to load data from an AJAX requestion, with the text from the request being the titleproperty of the tooltip. My AJAX request works fine, but I have two problems:
Why isn't the data from the AJAX call making its way into the tooltip?
How can I use my ttManager object to encapsulate the tooltip's state?
Currently, when the page first loads and I click on #btnSubmit in the console I see
success and the correct data from the console.log(ttManager) line
$(document).ready(function () {
//this object's title attribute will be the value of ttManager.title seen below
var ttManager = {
title: '',
setTitle: function (data) {
this.title = data;
}
}
var ajaxCall = function () {
//this returns the top five results of text from a query
$.ajax({
type: "POST",
contentType: "application/json",
url: "Service.asmx/GetDrugs",
dataType: "json",
success: function (data) {
console.log('success');
ttManager.title = data.d;
//inside this function I want to set ttManager.title equal to the data.d
console.log(ttManager);
},
error: function (xhr) {
console.log('failed: ' + xhr.status);
}
});
}
$('#btnSubmit').tooltip({
//reference to ajax call
//title is the attribute responsible for displaying text in the tooltip
//I need to use a reusable object to set the text property instead of referencing ajaxCall
//would it be better if there below were title: ttManager.title?
title: ajaxCall,
trigger: 'click',
placement: 'right'
});
});
I'm pretty sure that I need a callback function somewhere, but I'm not sure where. Any future pointers would be appreciated, too. Thanks.
First, a little explanation of bootstrap's tooltip plugin. The tooltip displayed will pull from the elements title attribute if there's one present, otherwise it will use the title argument passed.
The next thing you need to understand is that ajax calls are asynchronous. This means code will continue to run while it's waiting for a response. So, for example, if I do something like this
$.ajax({
URL: 'google.com',
success: function(){
console.log('yay');
}
});
console.log('woohoo');
you'd see "woohoo" in the console before "yay". So, currently, you're calling $('#btnSubmit').tooltip before your ajax query has altered the state of ttManager.
The other issue is that you're currently not doing anything with ttManager in relation to bootstrap. I feel like I should also mention that the ttManager object seems meaningless here.
Personally, I would change my ajax success function to this (sets the title attribute, calls tooltip, then produces another click to make the tooltip appear)
success: function(data) {
$('#btnSubmit').attr('title', data.d)
.tooltip({
trigger: 'click',
placement: 'right'
}).click();
}
remove the current $('#btnSubmit').tooltip... code currently there, and add in a one time click handler to call your ajax.
$('#btnSubmit').one('click', function() {
ajaxCall();
});

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