What I m missing to implement case insensitive search? - javascript

Here is my js file. I 've done everything in the server side. And implemented all basic and some advance feature of Datatable plugins. But the search function is case sensitive. If I search for "oil" it shows oil only but not OIL.
$(document).ready(function () {
var oTable = $('#myDataTable').dataTable({
"bServerSide": true,
"sPaginationType": "full_numbers",
"sAjaxSource": "/DB/AjaxOil",
"bProcessing": true,
"Search": {
"caseInsensitive": true
},
"aoColumns": [
{
"sName": "OilId",
"aTargets": [0], //Edit column
"mData": "OilId",
"bSearchable": false,
"bSortable": false,
"mRender": function (data, type, full) {
var id = full[0]; //row id in the first column
return "<a>"+id+"</a>";
}
},
{ "sName": "CommonName" },
{ "sName": "BotanicalName" },
{ "sName": "PlantParts" },
{ "sName": "Distillation" }
],
"columnDefs": [
{
"targets": [0],
className: "hide_column",
"searchable": false
}
]
});
});
And Here is my ajax function
public ActionResult AjaxOil(JQueryDataTableParamModel param)
{
IEnumerable<Oil> allOils = _context.Oils.ToList();
IEnumerable<Oil> filteredOils;
if (!string.IsNullOrEmpty(param.sSearch))
{
filteredOils = allOils
.Where(c => c.CommonName.Contains(param.sSearch)
||
c.BotanicalName.Contains(param.sSearch)
||
c.PlantParts.Contains(param.sSearch)
||
c.Distillation.Contains(param.sSearch));
}
else
{
filteredOils = allOils;
}
var sortColumnIndex = Convert.ToInt32(Request["iSortCol_0"]);
Func<Oil, string> orderingFunction = (c => sortColumnIndex == 1 ? c.CommonName :
sortColumnIndex == 2 ? c.BotanicalName :
c.PlantParts);
var distillationFilter = Convert.ToString(Request["sSearch_4"]);
var commonFilter = Convert.ToString(Request["sSearch_1"]);
var botanicalFilter = Convert.ToString(Request["sSearch_2"]);
var plantFilter = Convert.ToString(Request["sSearch_3"]);
if (!string.IsNullOrEmpty(commonFilter))
{
filteredOils = filteredOils.Where(c => c.CommonName.Contains(commonFilter));
}
if (!string.IsNullOrEmpty(botanicalFilter))
{
filteredOils = filteredOils.Where(c => c.BotanicalName.Contains(botanicalFilter));
}
if (!string.IsNullOrEmpty(plantFilter))
{
filteredOils = filteredOils.Where(c => c.PlantParts.Contains(plantFilter));
}
if (!string.IsNullOrEmpty(distillationFilter))
{
filteredOils = filteredOils.Where(c => c.Distillation.Contains(distillationFilter));
}
var sortDirection = Request["sSortDir_0"];
if (sortDirection == "asc")
filteredOils = filteredOils.OrderBy(orderingFunction);
else
filteredOils = filteredOils.OrderByDescending(orderingFunction);
var displayedOils = filteredOils
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength);
var result = from c in displayedOils
select new[] { Convert.ToString(c.OilId), c.CommonName, c.BotanicalName, c.PlantParts, c.Distillation };
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = allOils.Count(),
iTotalDisplayRecords = filteredOils.Count(),
aaData = result
},
JsonRequestBehavior.AllowGet);
}
P.s. The database has 5million row so please suggest with performance point of view too.

First of all you should not use _context.Oils.ToList(); then you will retrieve all your records from the database before filtering them. If you place the ToList() after .Take(param.iDisplayLength) all your selection code will be translated to a query in your database and only the relevant records will be retrieved. There is a difference between Contains executed by the Linq extension (case sensitve; see also this SO question) and the Contains that will we translated by the Entity Framework to a LIKE SQL statement (see this SO question and this video about tracing the SQL statements generated by your code).

As Shyju mentioned, refer to this post:
Case insensitive 'Contains(string)'
This will give you a wholistic idea of what to expect.
Here is a small excerpt from the post for your reference:
To test if the string paragraph contains the string word (thanks #QuarterMeister)
culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0
Where culture is the instance of CultureInfo describing the language that the text is written in.
In addition, I encourage you to visit this article which has an exhaustive comparison of various methods’ performances while checking if a string occurs within a string. This should help you decide what approach to take for better performance.
http://cc.davelozinski.com/c-sharp/fastest-way-to-check-if-a-string-occurs-within-a-string
Based on your question, you may have to create an extension method which will use different approach to preform check based on the type of input to achieve best performance.
Hope this helps!

Related

How can I bind data from db (jQuery) to an autocomplete?

I try to bind the data from a database tabel to an autocomplete edit field.
But somehow I don't succeed and need help.
I have the data on another webpage already in a dropdown combo. How can I access this data or replicate the funcionality for the edit field?
Thx for any hint.
-Adrian
I want the data from the db show up where I am using the country arry right now:
/*An array containing all the country names in the world:*/
var countries = ["Afghanistan","Albania","Algeria","Andorra","Angola","Anguilla","Antigua & Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia",...];
/*initiate the autocomplete function on the "myInput" element, and pass along the countries array as possible autocomplete values:*/
autocomplete(document.getElementById("myInput"), countries);
</script>
And to get the code from the database the following code seems to be used in another file of the project:
/**
* Loads skills into the table.
* #param {array} skills An array of skills.
*/
loadTable: function(skills) {
if(typeof skills != "object") skills = [];
if ( $.fn.dataTable.isDataTable( '#dyn_skills' ) ) {
$('#dyn_skills').DataTable().destroy();
}
var t = $("table.skills");
// remove tr elements which do not have
// the class "head", "template" or "status"
$("tr:not(.head,.template,.status)", t).remove();
// no skills found
if(! skills.length) {
$("tr.status td", t).empty().append(_("No skills found."));
$("tr.status td", t).show();
} else {
$("tr.status", t).remove();
}
if(skills.length) {if ( $.fn.dataTable.isDataTable( '#dyn_skills' ) ) {
DynTable = $('#dyn_skills').DataTable();
}
else {
DynTable = $('#dyn_skills').DataTable( {
"data" : skills,
"columns" : [
{ "data" : "id", "title" : _("Id") },
{ "data" : "preferredLabel" , "title" : _("Name") },
{ "data" : "description" , "title" : _("Description") }
],
"lengthMenu": [ 5, 10, 25, 50],
stateSave: true,
"language": {
"decimal": "",
"emptyTable": _("No data available in table"),
"info": _("Showing _START_ to _END_ of _TOTAL_ entries"),
"infoEmpty": _("Showing 0 to 0 of 0 entries"),
"infoFiltered": _("(filtered from _MAX_ total entries)"),
"infoPostFix": "",
"thousands": ",",
"lengthMenu": _("Show _MENU_ entries"),
"loadingRecords": _("Loading..."),
"processing": _("Processing..."),
"search": _("Search:"),
"zeroRecords": _("No matching records found"),
"paginate": {
"first": _("First"),
"last": _("Last"),
"next": _("Next"),
"previous": _("Previous")
},
"aria": {
"sortAscending": _(": activate to sort column ascending"),
"sortDescending": _(": activate to sort column descending")
}
}
} );
//read from url parameter and set datatables search value
$.urlParam = function(name){
var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
if (results==null) return null;
else return results[1] || 0;
}
var datatablesfilter = $.urlParam('datatablesfilter');
if(datatablesfilter == null) DynTable.search("").draw();
else DynTable.search(datatablesfilter).draw();
}
}
// On click the selected row gets the class "selected_row"
// The class "selected_row" is highlighted via CSS
// and used as a row selection marker for performing any action "edit" or "delete"
$('#dyn_skills tbody').on( 'click', 'tr:not(.status)', function () {
$("table#dyn_skills tr.selected_row").removeClass('selected_row');
$(this).addClass('selected_row');
event.stopPropagation();
} );
// binding event button #button_edit
// Read the data from the marked row and call the API function
$("button#button_edit").click( function () {
if (! $("table#dyn_skills tr.selected_row").length ){
alert(_("Please select a row from the table!!!"));
}
else
{
var skill_id = $("table#dyn_skills tr.selected_row td:eq(0)").text();
var skill_name = $("table#dyn_skills tr.selected_row td:eq(1)").text();
var skill_description = $("table#dyn_skills tr.selected_row td:eq(2)").text();
KPP.loadDialog(".template.skill-edit-dialog", null, function(self) {
$(".skill-id", self).empty().append(skill_id);
$(".skill-name", self).val(skill_name);
$(".skill-description", self).empty().append(skill_description);
$(".skill-send", self).click(function() {
KPP.Skill.edit(skill_id, {
"name": $(".skill-name", self).val(),
"description": $(".skill-description", self).val()
});
});
$(".skill-name", self).focus(); // set focus
});
}
} ); // end of button_edit

How do i search Boolean value which is displayed in string in jQuery datatable?

I have one field user_role which is boolean in Database. 1 = Manager and 2 = Normal user. I am displaying in a database like if user_role = 1 then it display Manager and so on. but the problem is when I search "Manager", this is not able to search in the user_role field. but when I search for "1", this will display all record in the manager field.
here is my code.
$(function () {
var url = "{{ asset('managers') }}";
var table = $('#managers-table').DataTable({
bProcessing: true,
ordering: true,
serverSide: true,
paging: true,
bRetrieve: true,
autoWidth: false,
ajax: {
url: url
},
aaSorting: [[1, 'desc']],
columns: [
{data: 'user_id'},
{data: 'email'},
{data: 'username'},
{
"data": 'user_role',
"render": function (data) {
return data == 1 ? "<span>Manager</span>" : "<span>Normal user</span>";
}
},
]
});
});
and here us my php code.
/**
* Display a listing of the Manager.
*
* #param Request $request
* #return Response
*/
public function index(Request $request)
{
$this->managerRepository->pushCriteria(new RequestCriteria($request));
if ($request->ajax()) {
return Datatables::of(Manager::IsDelete()->IsTestData()->get())->make(true);
}
return view('managers.index');
}
How do I search user_role field? please help if anyone is aware of this.
I got the solution. change the query in PHP code
public function index(Request $request)
{
$this->managerRepository->pushCriteria(new RequestCriteria($request));
if ($request->ajax()) {
return Datatables::of(Manager::select(DB::raw("user_id, email, username,is_active,(CASE WHEN (user_role = 1) THEN 'Manager' ELSE 'Normal User' END) as user_role"))->IsDelete()->IsTestData()->get())->make(true);
}
return view('managers.index');
}

Case insensitive search in search2.js

I am using select2.js in my project for drop down functionality. By default behaviour this is case sensitive i.e tag and Tag will be consider different.
But as per my requirement i required result populate is case insensitive i.e. when writing tag or Tag both need to considered to be small like in capital. I have tried many solution for this but non of that seems to working. I need to deal this client side only.
Issue is like this "https://groups.google.com/forum/#!topic/select2/vk86jUMfJTk"
$('#Taging').select2({
tags : true,
tokenSeparators : [ ',' ],
createSearchChoice : function(term) {
return {
id : term,
text : term,
n : "new",
s : ""
};
},
ajax : {
},
// Take default tags from the input value
initSelection : function(element, callback) {
var data = [];
$(splitVal(element.val(), ",")).each(function() {
data.push({
id : this,
text : this
});
});
callback(data);
},
});
sample Code
I modified my code and that works
createSearchChoice : function(term,data) {
if (term.trim().length > 0) {
if ($(data).filter(function () {
return this.text.toLowerCase().localeCompare(term.toLowerCase()) === 0;
}).length === 0) {
return {
id: term,
text: term,
n : "new",
s : "",
isNew: true // this is necessary to check if the item is newly added or not
};
}
}
},

Set jsTree Node to "Undetermined" State

I'm using jsTree to show a tree with checkboxes. Each level of nodes is loaded on-demand using the json_data plugin.
If a node's descendent is checked, then that node should be in an "undetermined state" (like ACME and USA).
The problem is, the tree starts out collapsed. ACME looks unchecked but should be undetermined. When I finally expand to a checked node, jsTree realizes the ancestors should be undetermined.
So I need to be able to put a checkbox in the undetermined state without loading its children.
With jsTree you can pre-check a box by adding the jstree-checked class to the <li>. I tried adding the jstree-undetermined class, but it doesn't work. It just puts them in a checked state.
Here's my code:
$("#tree").jstree({
plugins: ["json_data", "checkbox"],
json_data: {
ajax: {
url: '/api/group/node',
success: function (groups) {
var nodes = [];
for (var i=0; i<groups.length; i++) {
var group = groups[i];
var cssClass = "";
if(group.isSelected)
cssClass = "jstree-checked";
else if(group.isDecendantSelected)
cssClass = "jstree-undetermined";
nodes.push({
data: group.name,
attr: { 'class': cssClass }
});
}
return nodes;
}
}
}
})
My Question
How do I set a node to the undetermined state?
I had the same problem and the solution I found was this one:
var tree = $("#tree").jstree({
plugins: ["json_data", "checkbox"],
json_data: {
ajax: {
url: '/api/group/node',
success: function(groups) {
var nodes = [];
for (var i = 0; i < groups.length; i++) {
var group = groups[i];
var checkedState = "false";
if (group.isSelected)
checkedState = "true";
else if (group.isDecendantSelected)
checkedState = "undetermined";
nodes.push({
data: group.name,
attr: { 'checkedNode': checkedState }
});
}
return nodes;
},
complete: function () {
$('li[checkedNode="undetermined"]', tree).each(function () {
$(this).removeClass('jstree-unchecked').removeClass('jstree-checked').addClass('jstree-undetermined');
});
$('li[checkedNode="true"]', tree).each(function () {
$(this).removeClass('jstree-unchecked').removeClass('jstree-undetermined').addClass('jstree-checked');
});
$('li[checkedNode="false"]', tree).each(function () {
$(this).removeClass('jstree-checked').removeClass('jstree-undetermined').addClass('jstree-unchecked');
});
}
}
}
});
Hope it helps you!
Maybe this changed in the meanwhile...
But now (version 3.0.0) the really simple solution works:
{
id : "string" // will be autogenerated if omitted
text : "string" // node text
icon : "string" // string for custom
state : {
opened : boolean // is the node open
disabled : boolean // is the node disabled
selected : boolean // is the node selected
undetermined : boolean // is the node undetermined <<==== HERE: JUST SET THIS
},
children : [] // array of strings or objects
li_attr : {} // attributes for the generated LI node
a_attr : {} // attributes for the generated A node
}
Learned directly from the source code at: https://github.com/vakata/jstree/blob/6507d5d71272bc754eb1d198e4a0317725d771af/src/jstree.checkbox.js#L318
Thank you guys, and I found an additional trick which makes life a little better, but it requires a code change in jstree.js. Looks like an oversight:
Look at the get_undetermined function, and scan for the keyword break. That break should be a continue.
If you make that one change, then all you need to do is provide the state (for the main object and its children), and jstree will automatically take care of cascading upwards for undetermined state. It was bailing out early from the scripting and failing to catch all the undetermined nodes properly, requiring the above ugly workarounds for styling and such.
Here's my config (no special attrs or complete() function required) using AJAX:
var tree = $('#jstree').jstree({
"core": {
"themes": {
"variant": "large"
},
'data': {
'url': function (node) {
return "{{API}}/" + node.id + "?product_id={{Product.ID}}"
},
'dataType': 'json',
'type': 'GET',
'success': function (data) {
if (data.length == 0) {
data = rootStub
}
return {
'id': data.id,
'text': data.text,
'children': data.children,
'state': data.state,
}
}
}
},
"checkbox": {
// "keep_selected_style": false,
"three_state": false,
"cascade": "undetermined"
},
"plugins": ["wholerow", "checkbox"],
});

DataTables add column dynamically to table

I'm using DataTables (datatables.net) to display data from an Ajax source and having trouble customizing it. One thing I would like to do is add a column so I can have for example an 'edit' button for each row.
The closest thing to that in the examples is here but I can't get that to work with an ajax source.
Currently, I'm using the following code to display my table:
fnServerObjectToArray = function ( aElements ){
return function ( sSource, aoData, fnCallback ) {
$.ajax( {
"dataType": 'json',
"type": "POST",
"url": sSource,
"data": aoData,
"success": function (json) {
var a = [];
for ( var i=0, iLen=json.aaData.length ; i<iLen ; i++ ) {
var inner = [];
for ( var j=0, jLen=aElements.length ; j<jLen ; j++ ) {
inner.push( json.aaData[i][aElements[j]] );
}
a.push( inner );
}
json.aaData = a;
fnCallback(json);
}
} );
}
}
$(document).ready(function() {
$('#example').dataTable( {
"bProcessing": true,
"sAjaxSource": 'get_data.php',
"fnServerData": fnServerObjectToArray( [ 'username', 'email' ] )
} );
});
Why don't you use fnRenderFunction in the aoColumns? As an example:
aoColumns: [ { "bVisible": false} , null, null, null, null,
{ "sName": "ID",
"bSearchable": false,
"bSortable": false,
"fnRender": function (oObj) {
return "<a href='EditData.php?id=" + oObj.aData[0] + "'>Edit</a>";
}
}
]
You can use it to format the value from the server side.
See similar example on the http://jquery-datatables-editable.googlecode.com/svn/trunk/ajax-inlinebuttons.html (ignore specific settings for the editable plugin)
I've created columns with edit button and links and so on, but usually i do everything server side by custominzg the data i return and then show/hide them with the aoColumns option. I don't really understand what you are tring to achieve: display server side data as a link?
Had the same problem a few months back. This is what I did.
By no means an elegant slution, but this worked.
As you might already know, DataTables do have an overload to accept Javascript Arrays.
So I made by $.ajax call. got my json, parsed it to a javascript array and then while parsing I created an extra element (an anchor tag) with href="edit.php?email=passed_email" Then on the column headers and added a column called Edit. Those values were fed to "aaData" and "aoColumns". And then the table was populated.
And BTW, if you looking for inline editing, check the following link.
DataTables editing example - with jEditableplugin
i have some RND on this problem and get this hope this will help you out.

Categories