How to highlight words in datatables on pagination event - javascript

I need to highlight multiple words inside datatables https://datatables.net/.
Currently, my script highlights words on the first page of the table. Words on the second page are not highlighted when you go to that page first time. But they are highlighted if you go to another page and then get back to the second page once again. And so on. I know, the words on the second page are not highlighted first time because the pagination event callback function called asynchronously. How to highlight words from the hilitWrdArray[] array on the pagination event?
$(document).ready(function() {
var table = $('#example').DataTable( {
searchHighlight: true
} );
new $.fn.dataTable.FixedHeader( table, {
alwaysCloneTop: true
});
var hilitWrdArray = ["junior", "software", "chief", "regional", "specialist"];
var myHilitor = new Hilitor('#example');
myHilitor.apply(hilitWrdArray.join());
$('#example').on('page.dt', function () {
myHilitor.apply(hilitWrdArray.join());
}.bind(null, myHilitor, hilitWrdArray));
} );
Here is full code example:
http://jsfiddle.net/sergibondarenko/emp5gp6o/12/

mark.js is a text highlighter compatible with DataTables. Have a look at these two examples:
https://jsfiddle.net/julmot/buh9h2r8/
https://jsfiddle.net/julmot/c2am6zfr/
Usage is as simple as:
$(function() {
// Initialize DataTables
var table = $('.datatables-table').DataTable({});
// Initialize mark.js on table "draw" (search)
table.on('draw', function() {
// Get context
var tableContent = $(table.table().body());
// Specify keyword
var keyword = ["junior", "software", "chief", "regional", "specialist"];
// Remove previous marks
tableContent.unmark();
// Mark the new search keyword
tableContent.mark(keyword);
});
});
This initializes mark.js on table "draw", which includes the pagination event.
You can also keep track on this issue regarding a DataTables plugin for mark.js.

Update js fiddle try this if helpful for you. //jsfiddle.net/emp5gp6o/14/

Related

Clear saveState on DataTable is not working perfectly

I am having a few problems working with DataTable jQuery plug-in in my project. There are more than 20 tables using DataTable. Below is the javascript placed on every page that are using table with DataTable.
$(document).ready(function() {
pageSetUp();
var responsiveHelper_datatable_fixed_column = undefined;
var breakpointDefinition = {
tablet : 1024,
phone : 480
};
var otable = $('#datatable_fixed_column_GroupEnquiry').DataTable({
"stateSave": true, // saves state using localStorage
"sDom": "<'dt-toolbar'<'col-xs-12 col-sm-6 hidden-xs'f><'col-sm-6 col-xs-12'<'toolbar'>>r>"+
"t"+
"<'dt-toolbar-footer'<'col-xs-12 col-sm-6 hidden-xs'i><'col-xs-12 col-sm-6'p>>",
"autoWidth" : true,
"oLanguage": {
"sSearch": '<span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span>'
},
"preDrawCallback" : function() {
// Initialize the responsive datatables helper once.
if (!responsiveHelper_datatable_fixed_column) {
responsiveHelper_datatable_fixed_column = new ResponsiveDatatablesHelper($('#datatable_fixed_column_GroupEnquiry'), breakpointDefinition);
}
},
"rowCallback" : function(nRow) {
responsiveHelper_datatable_fixed_column.createExpandIcon(nRow);
},
"drawCallback" : function(oSettings) {
responsiveHelper_datatable_fixed_column.respond();
}
});
otable.state.clear(); //to clear saveState, but only work if the page is load for the second time
// Apply the filter
$("#datatable_fixed_column_GroupEnquiry thead th input[type=text]").on( 'keyup change', function () {
otable
.column( $(this).parent().index()+':visible' )
.search( this.value )
.draw();
} );
});
Situation
The tables work perfectly with saveState. When user go to specific page (example: page 5), and click on view detail (load new detail page), and click back button (load previous page with table) and the table still stays on the current page (page 5). This is what I want.
Problem
When user clicks on the navigation and redirect to the table, it still loads the table with previous state (which is in page 5) instead of display the 1st page and without any search filter.
Expected result
Supposed when user click on navigation and load table, the table should be display fresh state (on page 1 and without any search filter).
Attempt:
I placed otable.state.clear() as the code provided above, to clean the saveState of the table when user clicked navigation and display table. But it behaves weirdly, it only works on the second clicks on navigation.
I have no idea how actually saveState works and it is necessary to give unique id (#datatable_fixed_column_GroupEnquiry) for each table? I have more than 20 tables in different pages. How to clean saveState on specific button (navigation) and loads a fresh state table.
If anyone else searching for the solution, this helped for me.
I had the case that i wanted to clear the state when I access the dataTable with a link or pressed on refresh.
I put the followed piece of code, above the init of the dataTable inside the $(document).ready()
if (performance.navigation.type != 2){ //checks if page is accessed through a link or refresh
var table = $('#orderHistoryTable').DataTable();
table.state.clear();
table.destroy(); // need to destroy the table, I don't know why..
}

Click on first item autocomplete jQuery ui

I'm trying to click on the first item of the list that displays autocomplete after searching:
$(function(){
$('#autocompleteplace').each(function(i, el) {
var $this = $(el);
$this.autocomplete({
source: $this.data('urlp'),
autoFocus: true,
minLength: 1,
select: function( event, ui ) {
$('#' + $this.data('id')).val(ui.item.id);
}
});
var region = '{{ form.vars.data.place.region|default('') }}';
$this.autocomplete("search", region, true);
var menu = $this.autocomplete("widget");
$(menu[0].children[0]).click();
});
});
This code is the same from here, which I tried in the same environment and it works. But in my example I get the data from the server, and it shows and selects the first item with autoFocus, but it doesn't click on it.
I just want to edit a post that uses a field with autocomplete (place), so when the form is shown I want it to have the place already selected.
I asked for a quick fix of that problem: retrieve the value of the item that its already stored, but it's easier and cleaner doing it in the form. My fix was modify the Transformer in my Symfony form. Since this is not a PHP topic, I'm not going into details.
In conclusion: there should be a better way to achieve that than forcing a click() event.

How to destroy bootstrap colorpicker?

I am using bootstrap colorpicker in my logic as given below : -
for (var i = 0; i < abc.length; i++) {
if (selectedValue == abc[i].name) {
var color = getColor(selectedValue);
$('.colorPicker').colorpicker('setValue', color).on(
'changeColor', function(ev) {
var colorCode = ev.color.toHex();
changeColor(colorCode);
}).on('hidePicker', function(ev) {
alert("Hiding colorpicker");
});
}
}
The above code gets called from a method everytime a user select some value in dropdown.
Problem :
Now when I open the colorpicker and close it by defocusing it. I get the alert "Hiding colorpicker" once in first go.
If I select another value from dropdown that fires the above given code again and then I open and close the color picker again. The I get the alert twice and so on in increasing numbers.
My Understanding:
My understanding is that I am initializing color picker with different values everytime the above code is fired ,So code is creating different instances of colorpicker on same ".colorPicker" class element. So I need to remove the previously created instance of colorPicker before initializing a new one.
What I tried:
I used the below given line as the first line in my method to destroy this first. But it's not working.
$('.colorPicker').colorpicker('destroy');
Any help that how can I destroy the colorpicker everytime and then use the new instance on every method call so that I can avoid multiple alerts of "Hiding colorpicker".

Can't find element using UI hash in Marionette Layout

I'm not sure why I can't get the button element using my UI hash. This is what my Layout looks like:
Layout: App.Base.Objects.BaseLayout.extend({
// Rest of the code left out for brevity
ui: {
btnSave: "#btnSave"
},
events: {
"click #ui.btnSave": "onSave"
},
onInitialize: function () {
this.listenTo(App.vent, "DisableSaveButton", function(val) {
this.disableSaveButton(val);
},this);
},
disableSaveButton: function () {
this.ui.btnSave.prop("disabled",val).toggleClass("ui-state-disabled",val);
},
onSave: function () {
alert("saved!");
}
})
In VS2013, when my breakpoint hits the line inside disableSaveButton method, I entered $("#btnSave") into the Watch window and I was able to get the element back. I could tell because it had a length of 1. From this, I know the button is rendered. However, if I enter this.ui.btnSave into the Watch window, I would get an element with length of 0.
My BaseLayout object is basically a custom object extended from Marionette.Layout
Marionette version: 1.8.8
Any ideas why I can't find the button element using this.ui.btnSave?
Thanks in advance!
Got some help from a coworker and the issue might be because the element is out of scope. Basically, inside the Layout object, 'this' does not contain the element. We were able replace 'this.ui.btnSave' with '$("#btnSave",this.buttonset.el)' and that works fine. buttonset is the region that actually contains the html element.
This seems like an inconsistency because even though the ui hash didn't work, the click event utilizing the ui hash did work.
UPDATE 6/3/2015:
Another coworker of mine provided a better solution. Basically, in my Layout I use a display function to display my view. It looks something like this:
Layout: App.Base.Objects.BaseLayout.extend({
// Rest of the code left out for brevity
display: function() {
$(this.buttonset.el).html(_.template($("#buttonset-view").html(), {"viewType": viewType}));
}
})
Basically, I'm saying to set the html of my region, which is this.buttonset.el, to my template's html. As of now, my layout doesn't know any of the elements inside the region. It just contains a region which displays the elements. So there is some sort of disconnect between my layout and the elements in my region.
The correct solution, as opposed to my earlier workaround, is to simply add the following line of code at the end:
this.bindUIElements();
From Marionette Annotated Source:
This method binds the elements specified in the “ui” hash inside the
view’s code with the associated jQuery selectors.
So this final code looks like this:
Layout: App.Base.Objects.BaseLayout.extend({
// Rest of the code left out for brevity
display: function() {
$(this.buttonset.el).html(_.template($("#buttonset-view").html(), {"viewType": viewType}));
this.bindUIElements();
}
})
With this, I was able to finally able to retrieve my element using this.ui.btnSave.

Show and hide dynamic jQuery UI Dialogs

I know this should be simple, but it doesn't appear to be working the way I hoped it would.
I'm trying to dynamically generate jQuery UI dialogs for element "help."
I want to toggle the visibility of the dialog on close (x button in dialog), and clicking of the help icon. This way, a user should be able to bring up the dialog and get rid of it, as needed, multiple times during a page view.
// On creation of page, run the following to create dialogs for help
// (inside a function called from document.ready())
$("div.tooltip").each(function (index, Element) {
$(Element).dialog({
autoOpen: false,
title: $(Element).attr("title"),
dialogClass: 'tooltip-dialog'
});
});
$("a.help").live("click", function (event) {
var helpDiv = "div#" + $(this).closest("span.help").attr("id");
var dialogState = $(helpDiv).dialog("isOpen");
// If open, close. If closed, open.
dialogState ? $(helpDiv).dialog('close') : $(helpDiv).dialog('open');
});
Edit: Updated code to current version. Still having an issue with value of dialogState and dialog('open')/dialog('close').
I can get a true/false value from $(Element).dialog("isOpen") within the each. When I try to find the element later (using a slightly different selector), I appear to be unable to successfully call $(helpDiv).dialog("isOpen"). This returns [] instead of true/false. Any thoughts as to what I'm doing wrong? I've been at this for about a day and a half at this point...
Maybe replace the line declaring dialogState with var dialogState = ! $(helpDiv).dialog( "isOpen" );.
Explanation: $(helpDiv).dialog( "option", "hide" ) does not test if the dialog is open. It gets the type of effect that will be used when the dialog is closed. To test if the dialog is open, you should use $(helpDiv).dialog( "isOpen" ). For more details, see http://jqueryui.com/demos/dialog/#options and http://jqueryui.com/demos/dialog/#methods.
I was able to get it working using the following code:
$("div.tooltip").each(function (index, Element) {
var helpDivId = '#d' + $(Element).attr('id').substr(1);
var helpDiv = $(helpDivId).first();
$(Element).dialog({
autoOpen: true,
title: $(Element).attr("title"),
dialogClass: 'tooltip-dialog'
});
});
// Show or hide the help tooltip when the user clicks on the balloon
$("a.help").live("click", function (event) {
var helpDivId = '#d' + $(this).closest('span.help').attr('id').substr(1);
var helpDiv = $(helpDivId).first();
var dialogState = helpDiv.dialog('isOpen');
dialogState ? helpDiv.dialog('close') : helpDiv.dialog('open');
});
I changed the selectors so that they're identical, instead of just selecting the same element. I also broke out the Id, div and state into separate variables.

Categories

Resources