I'm trying to call a funtion in textextjs method-
//my function
function GetAreaTags() {
return "some text";
}
//textext initializtion
$('#territory').textext({
plugins: 'tags prompt focus autocomplete ajax',
ajax: {
url: '/Admin/Search/GetTerritorySuggestions?area=' + GetAreaTags(),
dataType: 'json',
cacheResults: false
}
});
But GetAreaTags() is not being called. How can i make it happen?
It should work... But try this:
function GetAreaTags() {
return "some text";
};
var yourObj= {
plugins: 'tags prompt focus autocomplete ajax',
ajax : {
url: '/Admin/Search/GetTerritorySuggestions?area=' + GetAreaTags(),
dataType: 'json',
cacheResults: false
}
};
$('#territory').textext(yourObj);
console.log(yourObj.ajax.url);
If that doesn't work out try this:
function GetAreaTags() {
return "some text";
};
var yourObj= {
plugins: 'tags prompt focus autocomplete ajax',
ajax : {
url: function() {return '/Admin/Search/GetTerritorySuggestions?area=' + GetAreaTags()},
dataType: 'json',
cacheResults: false
}
};
$('#territory').textext(yourObj);
console.log(yourObj.ajax.url);
Check the console both times to see if your url is what you desire.
[EDIT: I rejected the edit by mistake, sorry about that]
Edit2
From s.k.paul's comment:
GetAreaTags() should execute every time i type in that textbox.
However, console says- 1. /Admin/Search/GetTerritorySuggestions?area=
2. localhost:12788/Admin/Dashboard/…}&q= 404 (Not Found)
Therefore you need another event handler to dynamically change the url (the plugin must be recalled with another url):
function GetAreaTags() {
return "some text";
};
$("#territory").keyup(function() {
var yourObj= {
plugins: 'tags prompt focus autocomplete ajax',
ajax : {
url: function() {return '/Admin/Search/GetTerritorySuggestions?area=' + GetAreaTags()},
dataType: 'json',
cacheResults: false
}
};
$('#territory').textext(yourObj);
console.log(yourObj.ajax.url);
});
However, this may be very heavy... The plugin expects you to have a single reference for your auto-complete resource. If you're dynamically changing it, it may reset the already existing stuff.
Edit3
Edit 2 : textextjs does not work at all now. And, url function returns
whole function text
This means the plugin doesn't handle well being recalled twice or more times in the same element. The only possible solution I am seeing is to change the plugin's code in order to dynamically change the resources according to your function...
Which makes me wonder, if it's easier for you to allow the user to have a broader data resource (include all areas) when typing, this way there would be only one URL and the plugin wouldn't have any trouble with that.
Related
I have an autocomplete field, and on type I go to the PHP/Database to retrieve the matching options.
Thing is, my suggestion list isn't exactly matches of the text. I explain:
Say I type "Jon". My list will bring from the database "John Doe", "Jonatan", etc. Only "Jonatan" will be visible as the suggestion to the input, but I do need them all, because it considers approximation (there's a soundex element on my backend search).
My JavaScript/Ajax code:
function prePatientsList(){
//I'm limiting search so it only starts on the second character
if (document.getElementById("name").value.length >= 2) {
try
{
listExecute.abort();
}catch(err) {
null;
}
var nome= $("#name").val();
var nomeList = "";
listExecute = $.ajax({
url: '/web/aconselhamento/Atendimento/PrePacientesAutocomplete',
type: "POST",
async: true,
datatype: 'json',
data: { nome: nome}
}).done(function(data){
source = JSON.parse(data);
});
$(function() {
$("input#nome").autocomplete({
source: source,
// I know I probably don't need this, but I have a similar component which has an URL as value, so when I select an option, it redirects me, and I'll apply you kind answer on both.
select: function( event, ui ) {
ui.item.label;
}
});
});
}
}
Thanks.
I think you'd have to set your remote endpoint directly as the autocomplete's source (e.g. similar to https://jqueryui.com/autocomplete/#remote) so that it's the backend which does all the filtering. Right now, the autocomplete effectively thinks you've fed it a static list of options from which further filtering should take place, and therefore it decides to handle the filtering itself.
Your code can be as simple as this I think, no need to have a separate handler or an ajax request outside the scope of the autocomplete.
$(function() {
$("input#nome").autocomplete({
minLength: 2, //limit to only firing when 2 characters or more are typed
source: function(request, response)
{
$.ajax({
url: '/web/aconselhamento/Atendimento/PrePacientesAutocomplete',
type: "POST",
dataType: 'json',
data: { nome: request.term } //request.term represents the value typed by the user, as detected by the autocomplete plugin
}).done(function(data){
response(data); //return the data to the autocomplete as the final list of suggestions
});
},
// I know I probably don't need this, but I have a similar component which has an URL as value, so when I select an option, it redirects me, and I'll apply you kind answer on both.
select: function( event, ui ) {
ui.item.label;
}
});
});
See http://api.jqueryui.com/autocomplete/#option-source for more info.
I have this code Ext.get('book').setValue('1');
Note: Loads the page and book value is set to 1. Not after page load
and book value change to 1.
It sets the book to value 1. But it does not trigger a change event. Is there a way to trigger the change event after page loads?
Edit:
In html script,
<script..>
$(document).ready(function () {
$("book").on("blur", function() {
//calls other function
}); // not called as blur is not invoked
});
</script>
<input id="book" type="book" value="" /><br />
In extjs,
var panel = Ext.create('Ext.grid.Panel', {
id: 'panel',
columns: [
var bookid = "new book";
Ext.Ajax.request({
params: { bookid: bookid},
function: function (response) {
Ext.get('book').setValue(bookid);
// after setValue, book will receive a change event(e.g .blur in html) and changes other functions
}
});
]
});
Your ajax request seems to be malformed, the function: function statement would be the place where you put normally success: function like in the following statement:
Ext.Ajax.request({
url: 'insert-your-http-endpoint-here',
params: {
bookid: bookid
},
success: function(response){
debugger; // -> setting this statement will show that you enter the success statement
Ext.get('book').setValue(bookid);
},
failure: function(response, opts) {
// something went wrong with your request
console.log('server-side failure with status code ' + response.status);
}
});
more info about how to use ExtJS or the specific function, you could find in the documentation (check if you have the correct version, ofcourse) which can be found here
From the above code, you don't need the debugger statement, but it could help if you want to check if you actually get into this code block or not, and what happens when you try to set the value.
Also, don't forget to check your console output when something is not working, maybe there was a problem that would be clearly indicated in the console log
I want to prevent from adding a category to the Select2 element if it fails creating the row first in my db. The action is not prevented when i call ev.preventDefault(); Nothing happens.. what is wrong?
$('#sel2').select2({
placeholder: 'Enter categories',
minimumInputLength: 3,
multiple: true,
ajax: {
url: 'async/get_categories.php',
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
q: term,
};
},
results: function (data, page) {
return {
results: data.items
};
},
cache: true
},
formatResult: format,
formatSelection: format
}).on('select2-selecting', function(e) {
console.log(e);
if (e.val == 4) {
// if category id equals 4
// do not add this category to select 2
// e.preventDefault();
// the above works just fine and its just for testing
}
// Is something wrong here?
var ev = e;
$.ajax({
type: 'POST',
url: 'async/create_profile_category.php',
data: {
profile_id: '1',
category_id: ev.val
},
success: function(response) {
console.log(response);
if (response.error === false) {
// category assigned successfully
} else {
// failed to assign category
// so i want now to prevent from adding to select2
console.log('should not add this category');
ev.preventDefault();
// the above is not working
}
},
error: function() {
alert('Failed to assign category!');
}
});
});
The AJAX request is made asynchronusly, so by the time it has finished the element has already been added. Even though you are calling ev.preventDefault(), it is too late for it to make a difference. So this leaves you with two options:
Make the request synchronusly, which will allow preventDefault to make the difference.
Make the request asynchronusly, and manually remove the element if it fails.
Both options have their pros and cons, and it's up to you to decide which option you go with.
Making the request synchronusly
Pros
The value will never be added if the request fails.
Works well in cases where the element cannot be added quite often.
Cons
Blocks the UI - So the user is potentially left with an unresponsive page while the request is made.
Making the request asynchronusly
Pros
Does not block the UI.
Works well in cases where elements typically can be added.
Cons
The value will always show up for the user, even if it fails later.
You must manually unset the new option.
What's important to consider here is the user experience of both options. When making synchronus requests, it's not uncommon for the browser to stop relaying events - which gives the illusion that the UI has locked up and the page has gone unresponsive. This has the benefit of ensuring that the value never shows up if it isn't allowed. But if users typically can add the elements, it also has the downside of complicating the most common use case.
If users can usually add elements, then it is a better experience to add the element while the request is being made, and then notifying the user later (while removing the element) if there was an issue. This is very common is web applications, and you can see it being used in many places, such as the Twitter and Facebook like buttons (where requests usually work), as well as places on Stack Overflow.
There is a way to get around this with version4 of the select2 library.
on select2:selecting we cancel the preTrigger event. Which will stop the select2:select event. We do our ajax call. On success we then get out Select2 instance then call the trigger of the Observer that way it by passes overwritten trigger method on your select2 instance.
The call method needs your select2 instance as the context so that the existing listeners are available to call.
var sel = $('#sel');
sel.select2(config);
sel.on('select2:selecting', onSelecting);
function onSelecting(event)
{
$.ajax({
type: 'POST',
url: 'async/create_profile_category.php',
data: {
profile_id: '1',
category_id: event.params.args.data.id
},
success: function(event, response) {
console.log(response);
if (response.error === false) {
// category assigned successfully
// get select2 instance
var Select2 = $users.data('select2');
// remove prevented flag
delete event.params.args.prevented;
// Call trigger on the observer with select2 instance as context
Select2.constructor.__super__.trigger.call(Select2, 'select', event.params.args);
} else {
// failed to assign category
// so i want now to prevent from adding to select2
console.log('should not add this category');
}
}.bind(null, event),
error: function() {
alert('Failed to assign category!');
}
});
event.preventDefault();
return false;
}
here how I did it for yii2 Select2 integrated into Gridview:
'pluginEvents' => [
'select2:selecting' => "
function(event)
{
var select2 = $('#types-" . $model->id . "');
select2.select2('close');
$.post('update',{id: " . $model->id . ", type_id: event.params.args.data.id})
.done (function(response)
{
select2.val(event.params.args.data.id);
select2.trigger('change');
})
.fail(function(response)
{
krajeeDialog.alert('Error on update:'+response.responseText);
});
event.preventDefault();
return false;
}",
],
it allows to asynchoronous update data in the grid using select2 and ajax and return it to previous value if there was an error on updating.
I have a following javascript function mixed with MVC controller actions calls:
var loadPartialChapterAfterAnswer = function () {
$.ajax({
url: '#Url.Action("IsAuthenticated", "Story")',
type: "POST",
success: function(data) {
var isAuthenticated = data;
if (isAuthenticated) {
if ('#Model.IsPersonality' == 'True') {
loadPartialChapter();
} else {
$("#chapterContainer").load('#Url.Action("GetNextQuestion", "Story")' + '?storyId=' + '#Model.Id', function () {
selectedCounter = 0;
showOnlyOneQuestion();
});
}
} else {
window.location.href = '#Url.Action("RedirectToHomeRoute", "Home")';
}
},
error: function() {
alert("Error");
}
});
};
Every time I select one checkbox on my page(view) this function is called. Code works great in all browsers except in IE. In IE the ajax url #Url.Action("IsAuthenticated", "Story") is called OK every time, but the other controller action '#Url.Action("GetNextQuestion", "Story")' + '?storyId=' + '#Model.Id' is called only when the IE's browser debugger is turned on. When IE's debugger window is off this second MVC action is never called.
Any help is highly appreciated!
SOLUTION
I added at the beginning of my page this code:
<script>
$.ajaxSetup({
cache: false
});
</script>
and now it works! Thanks all for your effort.
I read something about IE having issues with JQuery load function
Try to replace it with regular $.ajax with cache: false option hopefully it will resolve the issue.
Check this topic
Add controller to this: #Url.Action("GetNextQuestion")'
Without controller specified it place controller which return view last.
I have a simple jQuery function that resizes text areas, and I want it to apply to all text areas.
For the most part, this works great:
$(document.ready(function(){$("text_area").resizer('250px')});
However, because it is only called once when the document is ready, it fails to catch text areas that are later added onto the page using Ajax. I looked at the .live() function, which seems very close to what I'm looking. However, .live() must be bound to a specific event, whereas I just need this to fire once when they're done loading (the onLoad event doesn't work for individual elements).
The only thing I can get working is a really obtrusive inclusion of the JavaScript call directly into the Ajax. Is that the recommended way to be doing this?
Edit: Here is the rails source code for what it does for Ajax requests:
$('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
var link = $(this);
if (!allowAction(link)) return false;
if (link.attr('data-remote') != undefined) {
handleRemote(link);
return false;
} else if (link.attr('data-method')) {
handleMethod(link);
return false;
}
});
// Submits "remote" forms and links with ajax
function handleRemote(element) {
var method, url, data,
dataType = element.attr('data-type') || ($.ajaxSettings && $.ajaxSettings.dataType);
if (element.is('form')) {
method = element.attr('method');
url = element.attr('action');
data = element.serializeArray();
// memoized value from clicked submit button
var button = element.data('ujs:submit-button');
if (button) {
data.push(button);
element.data('ujs:submit-button', null);
}
} else {
method = element.attr('data-method');
url = element.attr('href');
data = null;
}
$.ajax({
url: url, type: method || 'GET', data: data, dataType: dataType,
// stopping the "ajax:beforeSend" event will cancel the ajax request
beforeSend: function(xhr, settings) {
if (settings.dataType === undefined) {
xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
}
return fire(element, 'ajax:beforeSend', [xhr, settings]);
},
success: function(data, status, xhr) {
element.trigger('ajax:success', [data, status, xhr]);
},
complete: function(xhr, status) {
element.trigger('ajax:complete', [xhr, status]);
},
error: function(xhr, status, error) {
element.trigger('ajax:error', [xhr, status, error]);
}
});
}
So in my particular case, I've got a link, that has data-remote set to true, which points to a location that will return JavaScript instructing a form containing a text area to be appended to my document.
A simple way to do this would be to use ajaxComplete, which is fired after every AJAX request:
$(document).ajaxComplete(function() {
$('textarea:not(.processed)').resizer('250px');
});
That says "every time an AJAX request completes, find all textarea elements that don't have the processed class (which seems to be added by the resizer plugin -- terrible name for its purpose!) and call the resizer plugin on them.
You may be able to optimise this further if we could see your AJAX call.
Generally speaking, I would do it this way..
$.ajax({
type : "GET",
url : "/loadstuff",
success: function(responseHtml) {
var div = $("#containerDiv").append(responseHtml);
$("textarea", div).resizer("250px");
}
});
Wondering if you could use .load for this. For example:
$('text_area').load(function() {
$("text_area").resizer('250px');
});