I'm using the select2 jQuery plugin (V4) and from what I can see they don't have an onInitialized event; but I need to run some code after it has been initialized.
By Initialized I mean that it has completed and that all elements associated to it are now ready.
I seen this question, but none of the answers seem to address the issue of continually checking until it becomes available; like what if it's not there the first time you check, then the code you needed to run wouldn't run.
I thought of using setInterval with something like the above but wasn't sure if there was a better way?
The only way you can go async it's when you fetching remote data, so you can inject you callback in that ajax.
If you have several ajax calls use deferred:
var deffered1 = $.Deferred();
In your ajax calls after success and error use the following code to resolve those calls.
complete:function(){
deffered1.resolve()
}
And to subscribe for events:
$.when(deffered1, deffered2).done(function() {
// your initialized actions
})
If you have more than 1 select elements on your page which needs to be converted to select2 dropdown then you can use the following: Multi Select version
if you have just a single select on the page, you can go with the following:
Single Select option:
Hope it helps.
Related
I run a ajax call that updates interpolated value as a fully built selectbox element.
I would like to transform the created/returned selectbox into a chosen selectbox once it has finished fully loading otherwise it reverts back to a regular selectbox.
I have tried:
Listening to 'DOMSubtreeModified'(and other similar events) and then activating chosen lines but, these run too often and I have to know when the selectbox with all options are fully initiated. I can force initiation on each change, it's terrible - resource consuming and just plain wrong.
Initiate some callback on ajax return('ajax:complete' event) but, again - this does not guarantee the html controls are fully initiated as stated in this answer (and tested).
I've tried to set a onload event for the select control.
Main lines of code:
JavaScript call:
ajax('{{=URL('controller_name', 'func_name')}}', ['param1'], 'target_div');
Python controller returns(this returns a select control with option objects initiated in it and overrides the target_div inner html):
return SELECT(distinct_values, _id = 'selectbox_id' , _multiple = 'true' , _class='SelectBoxSingleDisabled');
Looking for a web2py oriented solution. No brute force/hacky stuff if possible. thanks!
There are several options (the first two are suggested here):
In the controller, add the Chosen initialization code to response.js -- this will be executed after the returned HTML is added to the DOM.
Add the Chosen initialization code to a script element after the select element:
CAT(SELECT(distinct_values, _id = 'manual_group_selectbox' , _multiple = 'true' ,
_class='SelectBoxSingleDisabled'),
SCRIPT('[Chosen code]'))
The third argument to the ajax() function can be a Javascript function that takes the data returned by the server. So, you could write a function that adds the returned HTML to the DOM and then initializes Chosen:
ajax(
'{{=URL('controller_name', 'func_name')}}', ['param1'],
function(html) {
[add html to DOM]
[initialize Chosen]
}
);
Set up a jQuery .ajaxSuccess() event handler, which should run after the ajax() function updates the DOM.
There is a modal dialog displaying mantle.ledger.transaction.AcctgTransEntry of the selected invoice. A button in the dialog calls a service which posts a GL transaction:
function postTransactionToGl() {
var invoiceId = $("input[id='showGlTransactions_Header_invoiceId_id']").val();
$.ajax(
{
type:"POST",
url:"${sri.buildUrl('postInvoiceToGl').url}",
data:
{
moquiSessionToken: "${(ec.getWeb().sessionToken)!}",
invoiceId: invoiceId
},
dataType:"json"
}
);
};
Then there is a JS function that displays the content of a table in the dialog. It calls a service which returns JSON data with entries included. I would like to fire both functions one after another, first post the transactions, then redraw the table. How shall I do that? Is there a way I can run the service, wait for the transaction to commit and then run the refresh?
This is more of a jQuery question than a Moqui question. The answer is simple: use the 'success' option in jQuery.ajax() to specify a function to call a method to do something. See:
http://api.jquery.com/jquery.ajax/
What you are describing is something that is much easier with an MVVM or MVC tool that runs in the browser. There are many of these out there and currently there is a proof of concept effort to use Vue JS in Moqui. With data binding the callback from the AJAX request would be easy, just update the data in the model and the view will automatically be updated. See the 'vuejs' branch in the moqui-framework and moqui-runtime repositories.
I want to attach a jQuery plugin function to an element on my site that exists only on one page. Currently, I'm using this conditional to prevent triggering the limiter function and throwing an error when there is no #advertiser_co_desc in view.
jQuery(document).ready(function($) {
var elem = $('#charNum');
if ($('#advertiser_co_desc').length) {
$('#advertiser_co_desc').limiter(180, elem);
}
});
On my website #advertiser_co_desc is present only on one page.
My solution does the job, but my qualm stems from the fact that the jQuery plugin code as well as the plugin function call presented above (they are both in the same file) get fetched by the browser and the condition is continuously evaluated regardless of whether a user ever gets to a page where #advertiser_co_desc exists.
Is the method I'm using optimal, or is there a better way to attach this particular JS only to the page where '#advertiser_co_desc` exists? Naturally, I wan to avoid adding my scripts in the same file with the PHP code.
Or you can wrap the plugin method as,
var _limiter = $.fn.limiter;
$.fn.limiter = function(limit, element) { // provide complete argmuments
if(this.length) {
_limiter.call(limit, element);
}
};
Make sure that plugin is loaded before this statements.
The best and optimal way to check existence of an element by jquery, is $('#advertiser_co_desc').length that you have used already. So no need to change your code.
I'm using Chosen jquery plugin. It shows "no results" if none found.
Is thera a way to trigger a function if no results found using this plugin?
Now, There is event chosen:no_results that you bind function to like this:
$('select.chosen-select').bind('chosen:no_results', chosenNoResults);
function chosenNoResults(evt, params) {
//Add new Option Logic
}
Refer Github for Reference
As a developer of Chosen I can safely tell you that there is currently no callback or event triggered when there are no results.
Although you could submit a feature request as an issue at the GitHub repository
The last few weeks there has been active development on Chosen, so changes of quick action upon your request are good.
I am using jQuery to apply some UI effects like adding a class to a number of elements, in the JS file i use :
$('.dataGrid').each(function(){
$(this).find('tr:odd').css('background-color', '#F7F8FA');
});
but when i use ajax to load an element with the class .dataGrid the rules up there doesn't apply, my solution was to make a function joins all cases like this one and call it every time i make an ajax request ! .. this off course is not a pro one .. i found .live() , i used and it worked fine with events like :
$('dataGrid').live('moveover', function(){ ... }); .
the .live solution is very good with events ... is there any way to use the same concept with the effects like mentioned up there ? ... i mean a way to reapply the rules set before, every time a change takes place on these elements ( adding new one for example )
I wish i was clear enough, Thanks in advance :)
The Livequery-plugin supports triggering functions when new nodes are added to the DOM.
Something like this should work:
$('.dataGrid').livequery(function() {
$(this).find('tr:odd').css('background-color', '#F7F8FA');
}
Depending on how you are loading elements i.e. which AJAX technique you are using, you can achieve this in many ways. If you are using jQuery Ajax then you can use the jQuery.when method.
Basically with this method you can have deferred execution. You can say something like "when the ajax call completes then do this function". The syntax goes like
$.when( $.ajax("test.aspx") ).then(function(ajaxArgs){
alert(ajaxArgs[1]); /* ajaxArgs is [ "success", statusText, jqXHR ] */
});
Following link will give you more information
http://api.jquery.com/jQuery.when/
Since you are using ajax to append your .dataGrid elements you could register a handler for ajaxComplete() that will handle the application of your :odd class.
$(document).ajaxComplete(function() {
$('.dataGrid').each(function(){
$(this).find('tr:odd').css('background-color', '#F7F8FA');
});
});