Sortable with scriptaculous problems - scriptaculous

Im following a few tutorials to sort a list, but i can't get the DB to update. The drag drop side of things is working, also, i javascript alert() the serialize list onUpdate and the order is printed out as follows:
images_list[]=20&images_list[]=19 etc...
So the sorting and dragging is working fine, i just cant get the database to update, this is my code.
<script type="text/javascript">
Sortable.create("images_list", {
onUpdate: function() {
new Ajax.Request("processor.php", {
method: "post",
parameters: { data: Sortable.serialize("images_list") }
});
}
});
processor.php code:
//Connect to DB
require_once('connect.php');
parse_str($_POST['data']);
for ($i = 0; $i < count($images_list); $i++) {
$id = $images_list[$i];
mysql_query("UPDATE `images` SET `ranking` = '$i' WHERE `id` = '$id'");
}
Any ideas would be great, thankyou!

Perhaps you have other tags in your elements for sorting. i would add tag: '':
<script type="text/javascript">
Sortable.create("images_list", {
onUpdate: function() {
new Ajax.Request("processor.php", {
method: "post",
parameters: { data: Sortable.serialize("images_list") }
});
},
tag: 'span'
});
</script>
Further i would check the path to your processor.php. I use:
new Ajax.Request("/youdir/processor.php", {
(Starting from DocumentRoot)

Related

Kendo UI - Get text of a treeview node

I have a problem with the Kendo UI TreeView and I'm looking for a solution for a while now. I found something similar here, but it didn't help me.
In my view I fill my TreeView like this:
Html.Kendo().TreeView()
.Name("treeview")
.BindTo((IEnumerable<TreeViewItemModel>) ViewBag.inlineDefault)
.Events(events => events
.Select("onSelect")
)
private IEnumerable<TreeViewItemModel> GetDefaultInlineData(ArrayList tables)
{
List<TreeViewItemModel> names = tables.Cast<TreeViewItemModel>().ToList();
List<TreeViewItemModel> inlineDefault = new List<TreeViewItemModel>
{
new TreeViewItemModel
{
Text = "Tables",
Items = names
}
};
return inlineDefault;
}
My onSelect funtion is the following:
<script>
function onSelect(e) {
$.ajax({
type: 'POST',
url: '/Editor/GetTableContent' ,
data: { tableName: ?????? },
success: function (data) {
$('#table').html(data);
}
}).done(function () {
alert('Done');
});
}
</script>
It calls a mehtod in my controller that needs the name of the selected node as parameter (string) to display the content of a table in a grid.
Is there a possibility to get what I need?
Thx for your help!
To get the text of the selected node in onSelect():
var nodeText = this.text(e.node);
this == the TreeView(can also use e.sender instead of this)
e.node == the selected node.
http://docs.telerik.com/kendo-ui/api/javascript/ui/treeview#events-select
http://docs.telerik.com/kendo-ui/api/javascript/ui/treeview#methods-text

Rails / Trix Editor save changes via AJAX to server

I am using the very simple to implement Trix Editor provided from Basecamp in an "Edit View".
How would one save automatically changes, without having the user to interact through the update button?
I am thinking about something like this:
(OLD SCRIPT)
window.setInterval(function() {
localStorage["editorState"] = JSON.stringify(element.editor)
}, 5000);
What I actually want to do:
post a ajax "post" request to the rails server. something like:
$('trix-editor').on('blur', function() {
var sendname = $('#note_name').val();
var sendlink = $('#linkinput').val();
var sendnote = $('input[name="note[note]"]').val();
$.ajax({
type: "POST",
url: "/notes",
data: { note: { name: sendname, link: sendlink, note: sendnote } },
success: function(data) {
alert(data.id);
return false;
},
error: function(data) {
return false;
}
});
(There is as well the problem with authentification and devise. Only if you are loged in you should be able to send an ajax post request ..??)
Even better would be to save changes only when the user changes some data, and then wait 5s and then push the updated data via json to the server. I have no clue how to do that...
PS: would have loved to tag this question with a "trix-editor" tag, sorry have not enought rep for doing so...
If you are using plain JavaScript, use a hidden input field:
<form>
<input type="hidden" id="noticeEditorContent"/>
<trix-editor input="noticeEditorContent" id="x" style="min-height: 200px;"></trix-editor>
</form>
Now you have access to the element with the ID x.
Which means, with getElementById, you can do something like that:
var richTex = document.getElementById("x");
With this variable, you can either set an interval as you already explained, or you are using jQuery to do the job:
$('#x').on('input', function() {
localStorage["editorState"] = JSON.stringify($('#x').val());
});
Just a suggestion. You can write this code a bit nicer and cleaner.
Now it depends. Is setting an interval every 5 seconds better or writing every change to the LocalStorage?
Suggestion:
Save the input when the user deselects the field:
$('#x').on('blur', function() {
localStorage["editorState"] = JSON.stringify($('#x').val());
});
Update: Here is a working JSFiddle.
so I came up with this code which saves via ajax on 'trix-blur' (which fires when the user disselects the trix-editor). There is only the question left if this code is secure enought with devise, or if now anyone can send data to be saved?!?
I have the authentification in the notes controller like that:
before_action :authenticate_user!
and here is the javascript part (with a custom messages functionality):
$('trix-editor').on('trix-blur', function() {
var sendname = $('#note_name').val();
var sendlink = $('#linkinput').val();
var sendnote = $('input[name="note[note]"]').val();
var sendid = $('#note_id').val();
$.ajax({
type: "PUT",
url: "/notes/" + sendid,
dataType: "json",
data: { note: { name: sendname, link: sendlink, note: sendnote }, id: sendid, commit: "Update Note" },
success: function(data) {
addMessage('auto saved ...', 'msg-success');
return false;
},
error: function(data) {
alert('error');
return false;
}
});
var addMessage = function(msg, msgclass) {
$('#notifications').append('<div id="msg" class="msg '+msgclass+'">'+msg+'</div>');
setTimeout(function() {
$('#msg:last-child').addClass('msgvisible');
}, 100);
displayMessage();
};
var displayMessage = function() {
setTimeout(function() {
hideMessage();
}, 2000);
};
var hideMessage = function() {
$('#msg').addClass('msghide');
setTimeout( function() {
deleteMessage();
}, 300);
};
var deleteMessage = function() {
$('#msg').remove();
if ($('#notificatosn').find('#msg') > 1) {
displayMessage();
}
};
});
Per the Trix project page the trix-editor emits different events on specific conditions.
The trix-change event is what you need; it fires whenever the editor’s contents has changed.
So, the first line of your JavaScript code could be
$('trix-editor').on('trix-change', function() {
/* Here will be your code to save the editor's contents. */
})

AngularJS and ui-grid interaction using $resource

I am brand new to angular JS and obviously to ui-grid as well. I got data to display in a grid using $resource and am trying to move to the next level by allowing editing and saving of rows etc.
I used Saving row data with AngularJS ui-grid $scope.saveRow as an example and created the Plunker http://plnkr.co/edit/Gj07SqU9uFIJlv1Ie6S5 to try it. But, for some reason I can't fathom, mine doesn't work and in fact it generates an exception at the line:
gridApi.rowEdit.on.saveRow(self, self.saveRow);
And I am at a total loss to understand why. I realize that the saveRow function is empty, but the goal at this stage is simply to get it called when the row has been edited.
Any help would be greatly appreciated.
The code of the Plunker follows:
(function() {
var app = angular.module('testGrid', ['ngResource', 'ui.grid', 'ui.grid.edit', 'ui.grid.rowEdit' /*, 'ui.grid.cellNav'*/ ]);
app.factory('Series', function($resource) {
return $resource('/api/series/:id', {
id: '#SeriesId'
});
});
var myData = [{
SeriesId: 1,
SeriesName: 'Series 1'
}, {
SeriesId: 2,
SeriesName: 'Series 2'
}];
app.directive('gridContent', function() {
var deleteTemplate = '<input type="button" value="Delete" ng-click="getExternalScopes().deleteRow(row)" />';
var commandheaderTemplate = '<input type="button" value="Add Series" ng-click="getExternalScopes().addNew()" />';
return {
restrict: 'E',
templateUrl: 'grid.html',
controllerAs: 'gridseries',
controller: function(Series) {
var self = this;
this.saveRow = function(rowEntity) {
i = 0;
};
this.gridOptions = {};
this.gridOptions.columnDefs = [{
name: 'SeriesId',
visible: false
}, {
name: 'SeriesName',
displayName: 'Name',
enableCellEdit: true
}, {
name: 'Command',
displayName: 'Command',
cellTemplate: deleteTemplate,
headerCellTemplate: commandheaderTemplate
}];
this.gridOptions.onRegisterApi = function(gridApi) {
self.gridApi = gridApi;
gridApi.rowEdit.on.saveRow(self, self.saveRow);
};
this.gridOptions.data = myData;
this.gridScope = {
deleteRow: function(row) {
var index = myData.indexOf(row.entity);
self.gridOptions.data.splice(index, 1);
},
addNew: function() {
self.gridOptions.data.push({
SeriesName: 'Add a name'
});
}
};
}
};
});
})();
I have no idea why the code didn't cut and paste properly but all the code is in the Plunker any way.
Thanks in advance.
I think the main problem here is that you're using a controller as syntax, rather than the $scope setup. Registering an event requires a $scope, as the event handler is then removed again upon the destroy event of that $scope.
A shorthand workaround is to use $rootScope instead, but this may over time give you a memory leak.
gridApi.rowEdit.on.saveRow($rootScope, self.saveRow);
Refer: http://plnkr.co/edit/Gj07SqU9uFIJlv1Ie6S5?p=preview
Since this code was also a bit old, I had to update to the new appScope arrangements rather than externalScope.

Auto-complete doesn't work as expected

I tried to implement this in MVC 5 with jquery ui 1.10.2
#{
ViewBag.Title = "Home Page";
Layout = null;
}
<p>
Enter country name #Html.TextBox("Country")
<input type="submit" id="GetCustomers" value="Submit" />
</p>
<span id="rData"></span>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery-ui.js"></script>
#Styles.Render("~/Content/themes/base/css")
<script type="text/javascript">
$(document).ready(function () {
$("#Country").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Home/AutoCompleteCountry",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function(data) {
response($.map(data, function(item) {
return { label: item.Country, value: item.Country };
}));
}
});
}
});
})
</script>
the server side is
...
[HttpPost]
public JsonResult AutoCompleteCountry(string term)
{
// just something to return..
var list = new List<string>() { "option1", "option2", "option3"};
var result = (from r in list
select r);
return Json(result, JsonRequestBehavior.AllowGet);
}
}
I have two issues
1. it open up drop down autocomplete with 3 dots but without the actual strings.
2. It has this annoying message of "3 results were found" - I'd like to eliminate it..
DO you have any idea how to face those two issues or neater way to implement it in MVC5?
The 3 bullet points and "3 results were found" is because you are missing the jQuery UI css file. That file will format a drop down that will look a lot better. You can customize how the dropdown looks with additional css.
Also, you are seeing 3 empty results because your JS is referencing item.Country ...
return { label: item.Country, value: item.Country };
But your server code is just sending 3 strings.
new List<string>() { "option1", "option2", "option3"};
To fix, change your JS to just reference the item (the string) ...
return { label: item, value: item};
OR, change your server code to send more complex objects
new List<Object>() { new { Country = "option1" }, new { Country = "option2" }, new { Country = "option3" } };
use return data in place of return { label: item.Country, value: item.Country };

get a column click in dataTables plugin instead of row

I have the following code that works great for row click, but I want the first and last column to be clickable and I want to be able to tell which column was clicked. I have the following code
$(document).ready(function() {
oTable = $('#mytable').dataTable();
var fa = 0;
$('#submit tbody td ').click(function() {
var gCard = $('#mytable tbody').delegate("tr", "click", rowClick);
});
function rowClick() {
fa = this;
var id = $("td:eq(1)", this).text();
cardNumber = $.trim(id);
$.ajax({
url : 'myurltopostto',
type : 'POST',
data : {
id : id
},
success : function(data) {
oTable.fnDraw(); //wanted to update here
},
error : function() {
console.log('error');
}
});
}
});
the code here is the row click
var gCard = $('#mytable tbody').delegate("tr", "click", rowClick);
what can I do for a cell click and get info.
using jquery plugin dataTables
thanks
When you do it $('#submit tbody td ').click(function() ... you bind click event to the td.
So, to get the first and last column click use the following:
$('td:first, td:last', '#submit tbody tr').on('click', function() {
// do what you want
});
demo1
updated 1:
Get last two columns:
jQuery('#mytable tr').each(function() {
jQuery('td', this).slice(-2).on('click', function() {
// do what you want
});
});
demo2
update 2: Get each column data on click last two columns
jQuery('#mytable tr').each(function() {
jQuery('td', this).slice(-2).on('click', function() {
// do what you want
var $columns = jQuery(this).siblings('td').andSelf();
jQuery.each($columns, function(i, item) {
alert(jQuery(item).html());
});
});
});
demo3
Just specify a column number instead of first, last, etc. The example below shows column 12. zero is first. It's easier that way.
td:eq(11)
$(document).ready(function() {
var table = $('#tableID').DataTable();
$('#tableID').on('click', 'tr', function () {
var data = table.row( this ).data();
alert( 'You clicked on '+data[0]+'\'s row' );
} );
} );
for more refer this link

Resources