Select2 with Ajax is not sending request - javascript

I'm using Select2 version 4.0.0 and trying to load a remote JSON from a PHP script that returns the already formated data that I need. The problem is that the forces of the darkness are making something, because I just can't send the request, there is no error, but there is no request sent, it just stays so quiet as a devil that I'm almost crying!
I'm using LiveScript and Jade as alternatives to JavaScript and HTML, but I'll translate'em here.
First, my markup defines the selectable field:
<select id="satan-hates-me"></select>
Then, I'm able to make it look like a selectable element:
$("#satan-hates-me").select2({
placeholder: "Hail",
minimumInputLength: 1,
ajax: { // Here that bad things happen, I mean, don't happen
url: "http://localhost/os/backend/TestServiceOrder.php?req=getEquipments",
dataType: "json",
type: "GET",
quietMillis: 50,
data: function(term) { return { term: term } },
results: function(data) { return data; }
}
});
I'm performing this wrapped in a load function, after page loading, it looks like a selectable, but sends no requests, and the script returns me exactly the required format, as example:
[{id: 1, text: "Sadness"}, {id: 2, text: "Depression"}]
And here goes. I can design compilers but I can't in the world make a plugin work with Ajax! Can somebody help me, please?

Finally resolved the issue.
<input> is not supported in select2 v4
.You have to use <select> element instead

In my case, it was a general select2-call of .select2-Elements in the footer of all my templates:
$('.select2').select2();
Event though my select for the Ajax-Request didn't have that class at all (I called it via an id), I had to change the above to
$('select.select2').select2({theme: 'classic'});
I guess select2() creates several elements with the class .select2, so that might interfere

Related

Extend Sitecore insert link functionality

I have an issue which I don't quite know how to approach.
I need to extend the Sitecore Insert link functionality: when I insert a link to a Sitecore Item, a certain icon, based on some logic (I've already created the logic for another user story(*)), needs to appear in the front of the link after "Insert" button is pressed, and of course, finally on the UI.
I was thinking on the following approach: after the item is inserted, the item's ID is sent to the backend via an Ajax call and the response is a mark-up with the values returned by the service I told you above at (*).
The issue is that I don't know where to start on or if my idea is ok.
Any help is welcome.
I found the answer:
In the RichText Commands.js file, I have added the following script which sends the item Sitecore ID to the API:
function scInsertSitecoreLink(sender, returnValue) {
if (!returnValue) {
return;
}
var url = returnValue.url;
var itemId = url.substring(url.indexOf("=") + 1, url.lastIndexOf("&"));
var $ = jQuery.noConflict();
$.ajax({
async: true,
type: "GET",
url: '/sitecore/api/Test/ThisIsTheTestApiCall',
data: JSON.stringify(itemId),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
alert(result);
}
});
[...]
}
First I have added var $ = jQuery.noConflict(); before the ajax call;
More info here: https://api.jquery.com/jquery.noconflict/
Then I've checked if there are any changes over the routes: RegisterHttpRoutes;
Profit.
You might be better to modify the renderField pipeline, because if you ever need to change these icons later, you're going to have to process every single link on your site.
To do that, you'll want to create a processor and have it run before Sitecore.Pipelines.RenderField.ExpandLinks, Sitecore.Kernel in the renderField pipeline so that you can use the dynamic links (which contain IDs) to figure out what icons you need. From there you can use HtmlAgilityPack.HtmlDocument to find and update the markup when the link is rendered.

Select2 - create ajax with pre-loaded options

I have a fairly simple requirement set, but cannot for the life of me figure out how to achieve it with Select2...
I would like to have an input on the page
Which the user can type into to trigger an AJAX call
Which also displays a pre-loaded list of options that the user can click on instead of typing to trigger the AJAX.
If you close (blur) the input and then reopen it again then the previously loaded AJAX responses should still be displayed (instead of the options being blank and you having to start typing to load them again).
I can do #1 and #2 (or #1 and #3 of course!), but I cannot get all three requirements in one input field. I've not found any way to do #4.
Effectively, to achieve #3, I guess I'm looking for a way to inject my shortlist into what are normally the ajax-returned options and use something like #4 to make sure these are not cleared when the field is opened.
Is there a way to initialise the (normally Ajax loaded) options for a Select2 field? I've tried passing in data but it doesn't work, I tried using initSelection until I realised that wasn't relevant, I've tried all sorts of things, but to no avail...
Hopefully this is possible and I've just missed an option somewhere!
P.S. I've read several threads on Stack with similar titles to this but none of them seem to answer this question. If I've missed the vital one just let me know!
I think you can do this if you use Select2's query option, rather than the ajax option. That way you can make the ajax request if any characters have been typed, but show the default list if no characters have been typed.
If your default options are defined like this:
var DEFAULT_OPTIONS = [
{ id: 'def1', text: 'Default Choice 1' },
{ id: 'def2', text: 'Default Choice 2' },
{ id: 'def3', text: 'Default Choice 3' }
];
You could do the following:
var lastOptions = DEFAULT_OPTIONS;
$('#select').select2({
minimumInputLength: 0,
query: function(options) {
if (options.term) {
$.ajax({
type: 'post', // Or 'get' if appropriate
url: 'your_ajax_url',
dataType: 'json',
data: {
term: options.term // Change name to what is expected
},
success: function(data) {
lastOptions = data;
options.callback({ results: data });
}
});
} else {
options.callback({ results: lastOptions });
}
}
});
jsfiddle

Dynamic use of g:message in Javascript

is there an easy way to use the g:message functionality in a dynamic way in Javascript, e.g.
function get_i18n( myAttr ) {
return "${message(code:'" + myAttr + "')} ";
}
so that I can perform the function call
pl_get_i18n( "xyz" )
for the predefined i18 attribute xzy ?
Like here, but dynamic: https://stackoverflow.com/a/8296812/1779814
PS: The JS code is included in the GSP file.
The short answer is "no". GSP tags can only be executed on the server-side, not by the browser (i.e. JavaScript).
However, I would expect there is at least one Grails plugin that does the following:
creates a JavaScript object containing the messages defined in your messages*.properties file(s)
provides a JavaScript function that enables you to resolve messages from this object
So although it's not possible to execute GSP tags in the browser, it doesn't seem terribly difficult to provide equivalent functionality in JavaScript. I would be amazed if there isn't already a Grails plugin that does this.
Here is a very simplistic example of how you can use AJAX to fetch a message code from the server.
// AjaxMessageController.groovy
package example
import grails.converters.JSON
class AjaxMessageController {
def index() {
render [message: message(code: param.code)] as JSON
}
}
Then within your page you can just use an ajax call (jQuery based) in this example to look up a message code:
var someMessageCode = 'something.you.want';
$.ajax({
dataType: 'json',
url: '${createLinK(controller: "ajaxMessage", action: "index"}',
data: {code: someMessageCode},
success: function(data) {
window.alert(data.message);
}
});

jquery.pageless scrape

I am using the jquery.pageless plugin. It implements infinite scrolling by grabbing the params generated by a paginate method in the controller.
I am trying to pass custom parameters, such as a user ID, to my pageless function. This works when I load the function in js.erb, as follows:
$('#relationship_list').pageless({ totalPages: "<%= #reviews.count %>"/5+1
, url: '/reviews'
, params: {id: "<%= params[:id] %>"}
, loaderMsg: "loading"
});
This works as desired. However, I DON'T want to load my page remotely, and so I need to find a way to implement this in javascript, unobtrusively (I don't want to integrate a script directly in my view, I want to place the code in application.js).
That means I have to find a way to 'translate' code like <%=params=> to a variable that the pageless call can read from the controller. But how? I really have no idea how to do this.
I think this is a question best for people who know jquery.pageless already, and since it's so general there's no point in my adding my own code to this post - please comment if disagree!
This is the solution I picked. Any tips on whether this was the appropriate way to go is welcome:
if($('#relationship_list').length){
$.ajax({
type: 'GET',
url: '/users/'+$('.user_info').attr("id"),
dataType: 'json',
success: function(response){
$('#relationship_list').pageless({ url: '/reviews'
, totalPages: response["count"]/5+1
, loaderMsg: "loading"
, params: {id: response["id"]}
});
}
});
}
What this does is make an ajax call to the controller, and render a json param with the key parameters. I then use these parameters to implement the .pageless function.
Note that in order to get the original user ID I actually have a div that contains the user ID, and so I grab that from the page. The user ID is no state secret but if anyone has a tip on how to grab an html parameter (the ID is in params[:id] in my rails code) I would be super grateful

how to use JSON for an error class

Hey all. I was fortunate enough to have Paolo help me with a piece of jquery code that would show the end user an error message if data was saved or not saved to a database. I am looking at the code and my imagination is running wild because I am wondering if I could use just that one piece of code and import the selector type into it and then include that whole json script into my document. This would save me from having to include the json script into 10 different documents. Hope I'm making sense here.
$('#add_customer_form').submit(function() { // handle form submit
The "add_customer_form" id is what I would like to change on a per page basis. If I could successfully do this, then I could make a class of some sort that would just use the rest of this json script and include it where I needed it. I'm sure someone has already thought of this so I was wondering if someone could give me some pointers.
Thanks!
Well, I hit a wall so to speak. The code below is the code that is already in my form. It is using a datastring datatype but I need json. What should I do? I want to replace the stupid alert box with the nice 100% wide green div where my server says all is ok.
$.ajax({
type: "POST",
url: "body.php?action=admCustomer",
data: dataString,
success: function(){
$('#contact input[type=text]').val('');
alert( "Success! Data Saved");
}
});
Here is the code I used in the last question, minus the comments:
$(function() {
$('#add_customer_form').submit(function() {
var data = $(this).serialize();
var url = $(this).attr('action');
var method = $(this).attr('method');
$.ajax({
url: url,
type: method,
data: data,
dataType: 'json',
success: function(data) {
var $div = $('<div>').attr('id', 'message').html(data.message);
if(data.success == 0) {
$div.addClass('error');
} else {
$div.addClass('success');
}
$('body').append($div);
}
});
return false;
});
});
If I am right, what you are essentially asking is how you can make this piece of code work for multiple forms without having to edit the selector. This is very easy. As long as you have the above code included in every page with a form, you can change the $('#add_customer_form') part to something like $('form.json_response'). With this selector we are basically telling jQuery "any form with a class of json_response should be handled through this submit function" - The specific class I'm using is not relevant here, the point is you use a class and give it to all the forms that should have the functionality. Remember, jQuery works on sets of objects. The way I originally had it the set happened to be 1 element, but every jQuery function is meant to act upon as many elements as it matches. This way, whenever you create a form you want to handle through AJAX (and you know the server will return a JSON response with a success indicator), you can simply add whatever class you choose and the jQuery code will take over and handle it for you.
There is also a cleaner plugin that sort of does this, but the above is fine too.
Based on your question, I think what you want is a jQuery selector that will select the right form on each of your pages. If you gave them all a consistent class you could use the same code on each page:
HTML
<form id="some_form_name" class="AJAX_form"> ... </form>
Selector:
$('form.AJAX_form")

Categories