Multiple Jquery ui autocomplete on one page - jquery-ui

I'm using the jQuery UI Autocomplete. I'm using it on three different input. So I have:
input id 1
autocomplete with xml data 1
input id 2
autocomplete with xml data 2
input id 3
autocomplete with xml data 3
I also have an event like this:
$(".ui-autocomplete li a").live("click",function(){
doSearch($(this).text());
});
The problem is that this event takes place on all three of the autocomplete.
What do I have to change in the event code or elsewhere to bind the event to a specific input/autocomplete. So I want to have event 1, 2, 3 corresponding to the different sets of input/autocomplete.

If I understand your question correctly, you want to pass either the autocomplete element or its index to doSearch(), in addition to the item text.
Passing the autocomplete element is as simple as using closest():
function doSearch(autocomplete, itemText)
{
// ...
}
$(".ui-autocomplete li a").live("click", function() {
var $this = $(this);
doSearch($this.closest(".ui-autocomplete"), $this.text());
});
Passing its index is a little trickier and can be achieved with index():
function doSearch(autocompleteIndex, itemText)
{
// ...
}
$(".ui-autocomplete li a").live("click", function() {
var $this = $(this);
doSearch($this.closest(".ui-autocomplete").index(".ui-autocomplete"),
$this.text());
});
Note in passing that bind(), delegate() and live() have been superseded by on() since jQuery 1.7, so you might want to use it to register your handler:
$(document).on("click", ".ui-autocomplete li a", function() {
// ...
});
If your autocomplete elements have a common non-dynamic ancestor, you can also apply on() to that element instead of document to gain a little performance.

Related

Rails nested Ajax forms on ajax:send only for top form

I have an ajax form that has a remote true link_to and a nested remote form that lead to other actions.
I need to use a listener to perform some actions on the top level form:
$(document).on('ajax:send', 'form[data-remote=true]', function (event) {
event.stopPropagation();
var $form = $(this);
...
$form.unbind("ajax:success").on('ajax:success', function (data) {
// do something
}).on('ajax:complete', function () {
// do something else
});
});
Problem is that the nested link_to and nested form trigger this listener no matter what I do.
I end up deviating from the Rails standards sadly, which is not what my problem is here, just HOW do you tell the on('ajax:send) function to only work IF the form is the top one?
I was thinking maybe to grand the URL from the ajax:send returned data with
$(document).on('ajax:send', 'form[data-remote=true]', function (event) {
[data, status, xhr] = event.detail
...
but this feels like a nightmare. Any suggestions?

Updating list in view Asp.net mvc razor

I have 2 lists in a view. What I want to do is that pick elements from list1 and update list2 with selected elements everytime I pick one. I tried to use PartialView (I don't know if it's correct approach or not) but I failed. I have a function in controller that fills a list by selected items. What needs to be done is updating the view dynamically. Can you suggest me a roadmap for this?
Update
I forgot to say that I have done this with javascript. But I feel like it's the long way when it comes to some validations (checking duplications etc.)
$(document).ready(function (){
$("#allPlayersList a").on("click", function () {
var options = $(this).clone();
$("#thisWeekList").append(options);
});
});
Just create an html list. See if this link helps. https://codepen.io/alexander-holman/pen/QNQrvz. You can also populate the values from database
Then you can get the selected element by javascript like this
var input = document.getElementById('Something').value;
Update after edited question
You can try something like
var listSelection = document.getElementById('Something').value;
Now you can create an api in the backend which accepts this value and returns a list based on it. Call that Api like this
&.ajax({
url: //url of api
data: {exactNameOfApiParameter : listSelection },
success: function(data){
for (i = 0; i < data.length; i++) {
$('<li>', { text: data[i] }).appendTo($('#list2'));
}
}
})
Make sure that id of second list is list2.

jquery ui table sortable with pagination

I am using jquery sortable with table and it works fine.
When I use pagination (I save the new order of datatble items in the DB via ajax post) the table lose the order and the new order will appear only if I refresh the page (because I will get the entities from the DB)
How can I kepping the new order while using pagination ?
$("tbody").sortable({
axis:'y',
placeholder: "ui-state-highlight",
group: 'no-drop',
handle: '.drag',
update: function (event, ui) {
var videoSortedIDS = $(this).sortable("toArray");
var ranks = [];
for (r = pageInfo.start; r < pageInfo.end; r++) {
ranks.push(r);
}
$.post(urlSort, {videoIDS: videoSortedIDS, videoRanks: ranks}, function (data) {
if (data.responseCode === 200) {
console.log(data.sortedEntities);
} else {
alert("Error");
}
});
}
}).disableSelection();
I found a solution ! Since the jquery Sortable don't affect the object instanciated with Datatable, I update every row in the Datatable table with the new content of the html table:
table.row(index).data(newRowContent).draw(false);
draw(false) to save the page state ;)

ajax request php class function

i have content listed in a div and i have a dropdown with various options to order and filter that content.
I'm using ajax to filter/order that content and is working but i use other php page with the content i want on the div that has the content, like this
function order(str){
$.post("order_products.php",
{
q: str,
},
function(data, status){
document.getElementById("txtHint").innerHTML = data;
});
}
What i wanted was to instead of putting the code (data) to change in another page just for that, i could put that code inside a class php function that i have.
<?php
class products{
function list(){
blablabla
}
That way i would "save space" and organize everything, considering that i have many other things to order/filter but i don't know to to make the ajax request to that function, or if it's possible without having a page in between and then get the response from the function and put it on the div.
You can do this using Laravel by setting up a route to a function that will do the ordering. Please note I've made a lot of assumptions in the following answer as I can't see all your code and have made it quite general, please adjust the code to your project or provide more details of your code if you don't understand the answer fully.
routes.php
Route::post('products/order', [
'as' => 'products.order',
'uses' => 'ProductsController#orderProducts'
]);
Your view (assuming you're using blade)
$txtHint = $('#txtHint'); // grab the reference to txtHint dropdown
$.post( '{{ route("products.order") }}', // hit our route
{
q: str,
},
function(data, status){
$txtHint.empty(); // clear the dropdown
// loop through the data and assign each element to the dropdown
$.each(data, function(value, key) {
$txtHint.append($("<option></option>")
.attr("value", value)
.text(key));
});
});
ProductsController.php
public function orderProducts()
{
$orderBy = \Input::get('q');
return \Products::lists('name', 'id')->orderBy($orderBy);
}
For outside of a framework just change the url to your php file and add in a data attribute for the method you require to be fired from the file.
$.post( 'products.php', // hit our route
{
action: 'order',
q: str,
},
...
Then in products.php you'd do something like this
if(isset($_POST['action']) && !empty($_POST['action'])) {
$action = $_POST['action'];
switch($action) {
case 'order' : order();break;
case 'otherFunction' : otherFunction();break;
}
}
function order()
{
// order logic here
// get $_POST['q']
// do your ordering
// return data as json
}
See here for similar question: using jquery $.ajax to call a PHP function

Custom binding for cleditor fails after sorting elements through knockout sortable

First up: check this fiddle.
I have sortable array of elements created with the Knockout sortable library. When I initially apply the binding the cleditor initializes fine.
However, when sortable elements are sorted, the cleditor fails to re-initialize (I'm not sure what happens but cleditor fails). The cleditor just displays "true" instead of actual value in Firefox, and nothing in all other browsers.
I'm trying to figure out where the problem is, whether it is on the custom binding, or jQuery-UI, or the Knockout sortable library?
I am not recieving any errors in my console.
ko.bindingHandlers.cleditor = {
init: function(element, valueAccessor, allBindingsAccessor) {
var modelValue = valueAccessor(),
allBindings = allBindingsAccessor();
var $editor = jQuery(element).cleditor({
height: 50,
controls: "bold italic underline | bullets numbering | undo redo"
});
$editor[0].change(function() {
var elementValue = $editor[0].doc.body.innerHTML;
if (ko.isWriteableObservable(modelValue)) {
modelValue(elementValue);
} else {
if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers'].cleditor) {
allBindings['_ko_property_writers'].cleditor(elementValue);
}
}
});
},
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()) || '',
$editor = jQuery(element).cleditor();
if ($editor[0].doc.body.innerHTML !== value) {
//$editor[0].doc.body.innerHTML = value;
$editor[0].doc.body.innerHTML = value;
$editor[0].focus();
}
}
};
How can I make the cleditor to work, even after the elements are sorted?
I found this resource, but I couldn't find anything wrong in code as said in that topic.
The link you provided was helpful. The CLEditor refresh method is the right way to update it after it's dragged. It just needs to be done at the correct time, using the sortable stop event.
stop: function(event, ui) {
$(ui.item).find("textarea").cleditor()[0].refresh();
}
http://jsfiddle.net/mbest/rh8c2/1/
I also worked to integrate this into your cleditor binding. In the init function:
jQuery(document).on('sortstop', function(event, ui) {
if (jQuery.contains(ui.item[0], element)) {
jQuery(element).cleditor()[0].refresh();
}
});
I also made a change in the update function to keep the <textarea> value in sync, because refresh updates the editor's value from the <textarea>:
$editor[0].updateTextArea();
http://jsfiddle.net/mbest/jw7Je/7/

Resources