optimize data loading in search with Select2 - javascript

I have a function to display the data in the search box, I used Select2, the function is fine, but it is slow when I want to see the data in the search box, even if I want to click on a data.
For your information, I use Select2 with a big table (> 20 000 entries).
How to fix this problem to avoid the time of data display?
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.full.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/i18n/fr.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdn.rawgit.com/eligrey/FileSaver.js/e9d941381475b5df8b7d7691013401e171014e89/FileSaver.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/spin.js/2.0.1/spin.min.js'></script>
.
.
function loadJson(error,values, select2Data){
root = values;
var select2_data = select2Data; // select2Data contains 22500 lines
root.x0 = height / 6;
root.y0 = 0;
_callerNode=root;
root.children.forEach(collapse);
tracePathAndNode(root);
var query = {}
$("#search").select2({
templateResult: function (item) {
var term = query.term || '';
if ( term=='') return item.text;
if (item.loading) {
return item.text;
}
return markMatch(item.text, term);
}
, language: "fr"
, language: {
searching: function (params) {
// Intercept the query as it is happening
query = params;
return 'Searching…';
}
}
,placeholder: "Zone de recherche"
,data: select2_data
,width: '100%'
});
}
function markMatch (text, term) {
// Find where the match is
var match = text.toUpperCase().indexOf(term.toUpperCase());
var $result = $('<span></span>');
// If there is no match, move on
if (match < 0) {
return $result.text(text);
}
// Put in whatever text is before the match
$result.text(text.substring(0, match));
// Mark the match
var $match = $('<span class="select2-rendered__match"></span>');
$match.text(text.substring(match, match + term.length));
// Append the matching text
$result.append($match);
// Put in whatever is after the match
$result.append(text.substring(match + term.length));
return $result;
}
.
.
function searchTree(obj,search,path){
var newSearch = search.replace(/ *\[ Resp:[^)]*\] */g, "");
var newSearch1 = search.replace(/ *\( [^)]*\) */g, "");
if(obj.desc === newSearch && newSearch1){
path.push(obj);
return path;
}
else if(obj.children || obj._children){
var children = (obj.children) ? obj.children : obj._children;
for(var i=0;i<children.length;i++){
path.push(obj);
var found = searchTree(children[i],newSearch && newSearch1,path);
if(found){
return found;
}
else{ path.pop();}
}
}
else{ return false;}
}
var allRhJson;
var select2_data_all;
var currentTypeSelection='ALL';
// loader settings
var opts = {
lines: 9, // The number of lines to draw
length: 9, // The length of each line
width: 5, // The line thickness
radius: 14, // The radius of the inner circle
color: '#EE3124', // #rgb or #rrggbb or array of colors
speed: 1.9, // Rounds per second
trail: 40, // Afterglow percentage
className: 'spinner', // The CSS class to assign to the spinner
};
var target = document.getElementById("tree-container");
var spinner = new Spinner(opts).spin(target);
d3.json("getJson.jsp?dataType=rh", function(data) {
spinner.stop();
allRhJson=data;
select2_data_all = extract_select2_data(allRhJson,[],0)[1];
loadJson(null,allRhJson, select2_data_all ) ;
});
$("#search").on("select2:select", function(e) {
var data = e.params.data.text;
var paths = searchTree(root,data,[]);
if(typeof(paths) !== "undefined"){
openPaths(paths);
}
else{
alert(data+" auncun résultat!");
}
})
d3.select(self.frameElement).style("height", "800px");

Related

How to get the parent child relationship between connected mxgraph

I'm trying to get simplified relationship between connected mxgraph
Question: I'm trying to get the simplified relationship, once the graph is drawn.
i'm trying to get relationship between connected nodes in json.
Note: solution must work for every drawn state.
Here is codepen:
https://codepen.io/eabangalore/pen/pmELpL
i want to get the relationship from above code snippet.
Expected output (from drawn relationship):
[
{"id":0,"parent":"#","text":"A","child":[{"cid":1,"connectionText":"Bangalore"}]},
{"id":1,"parent":0,"text":"B","child":[{"cid":2,"connectionText":""}]},
{"id":2,"parent":1,"text":"C","child":[{"cid":null,"connectionText":""}]}
];
Please refer codepen, as below snippet is not working.
<!--
Copyright (c) 2006-2013, JGraph Ltd
Dynamic toolbar example for mxGraph. This example demonstrates changing the
state of the toolbar at runtime.
-->
<html>
<head>
<title>Toolbar example for mxGraph</title>
<!-- Sets the basepath for the library if not in same directory -->
<script type="text/javascript">
mxBasePath = 'https://jgraph.github.io/mxgraph/javascript/src';
function setGraphData(){
var graphState ={"tagName":"mxGraphModel","children":[{"tagName":"root","children":[{"tagName":"mxCell","attributes":{"id":"0"}},{"tagName":"mxCell","attributes":{"id":"1","parent":"0"}},{"tagName":"mxCell","attributes":{"id":"2","value":"A","style":"","vertex":"1","parent":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"271.56251525878906","y":"82.44792175292969","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"3","value":"B","style":"","vertex":"1","parent":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"678.2291717529297","y":"106.89236450195312","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"4","value":"Bangalore","edge":"1","parent":"1","source":"2","target":"3"},"children":[{"tagName":"mxGeometry","attributes":{"relative":"1","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"5","value":"C","style":"","vertex":"1","parent":"1"},"children":[{"tagName":"mxGeometry","attributes":{"x":"1013.7847747802734","y":"83.55902862548828","width":"100","height":"40","as":"geometry"}}]},{"tagName":"mxCell","attributes":{"id":"6","edge":"1","parent":"1","source":"3","target":"5"},"children":[{"tagName":"mxGeometry","attributes":{"relative":"1","as":"geometry"}}]}]}]};
localStorage.setItem('graphState',JSON.stringify(graphState));
}
function html2json(html){
if(html.nodeType==3){
return {
"tagName":"#text",
"content":html.textContent
}
}
var element = {
"tagName":html.tagName
};
if(html.getAttributeNames().length>0){
element.attributes = html.getAttributeNames().reduce(
function(acc,at){acc[at]=html.getAttribute(at); return acc;},
{}
);
}
if(html.childNodes.length>0){
element.children = Array.from(html.childNodes)
.filter(
function(el){
return el.nodeType!=3
||el.textContent.trim().length>0
})
.map(function(el){return html2json(el);});
}
return element;
}
function json2html(json){
var xmlDoc = document.implementation.createDocument(null, json.tagName);
var addAttributes = function(jsonNode, node){
if(jsonNode.attributes){
Object.keys(jsonNode.attributes).map(
function(name){
node.setAttribute(name,jsonNode.attributes[name]);
}
);
}
}
var addChildren = function(jsonNode,node){
if(jsonNode.children){
jsonNode.children.map(
function(jsonChildNode){
json2htmlNode(jsonChildNode,node);
}
);
}
}
var json2htmlNode = function(jsonNode,parent){
if(jsonNode.tagName=="#text"){
return xmlDoc.createTextNode(jsonNode.content);
}
var node = xmlDoc.createElement(jsonNode.tagName);
addAttributes(jsonNode,node);
addChildren(jsonNode,node);
parent.appendChild(node);
}
addAttributes(json,xmlDoc.firstElementChild);
addChildren(json,xmlDoc.firstElementChild);
return xmlDoc;
}
</script>
<!-- Loads and initializes the library -->
<script type="text/javascript" src="https://jgraph.github.io/mxgraph/javascript/src/js/mxClient.js"></script>
<!-- Example code -->
<script type="text/javascript">
// Program starts here. Creates a sample graph in the
// DOM node with the specified ID. This function is invoked
// from the onLoad event handler of the document (see below).
function main()
{
setGraphData();
// Checks if browser is supported
if (!mxClient.isBrowserSupported())
{
// Displays an error message if the browser is
// not supported.
mxUtils.error('Browser is not supported!', 200, false);
}
else
{
// Defines an icon for creating new connections in the connection handler.
// This will automatically disable the highlighting of the source vertex.
mxConnectionHandler.prototype.connectImage = new mxImage('images/connector.gif', 16, 16);
// Creates the div for the toolbar
var tbContainer = document.createElement('div');
tbContainer.style.position = 'absolute';
tbContainer.style.overflow = 'hidden';
tbContainer.style.padding = '2px';
tbContainer.style.left = '0px';
tbContainer.style.top = '0px';
tbContainer.style.width = '24px';
tbContainer.style.bottom = '0px';
document.body.appendChild(tbContainer);
// Creates new toolbar without event processing
var toolbar = new mxToolbar(tbContainer);
toolbar.enabled = false
// Creates the div for the graph
var container = document.createElement('div');
container.style.position = 'absolute';
container.style.overflow = 'hidden';
container.style.left = '24px';
container.style.top = '0px';
container.style.right = '0px';
container.style.bottom = '0px';
container.style.background = 'url("editors/images/grid.gif")';
document.body.appendChild(container);
// Workaround for Internet Explorer ignoring certain styles
if (mxClient.IS_QUIRKS)
{
document.body.style.overflow = 'hidden';
new mxDivResizer(tbContainer);
new mxDivResizer(container);
}
// Creates the model and the graph inside the container
// using the fastest rendering available on the browser
var model = new mxGraphModel();
var graph = new mxGraph(container, model);
// Enables new connections in the graph
graph.setConnectable(true);
graph.setMultigraph(false);
// Stops editing on enter or escape keypress
var keyHandler = new mxKeyHandler(graph);
var rubberband = new mxRubberband(graph);
var addVertex = function(icon, w, h, style)
{
var vertex = new mxCell(null, new mxGeometry(0, 0, w, h), style);
vertex.setVertex(true);
var img = addToolbarItem(graph, toolbar, vertex, icon);
img.enabled = true;
graph.getSelectionModel().addListener(mxEvent.CHANGE, function()
{
var tmp = graph.isSelectionEmpty();
mxUtils.setOpacity(img, (tmp) ? 100 : 20);
img.enabled = tmp;
});
};
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rectangle.gif', 100, 40, '');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rounded.gif', 100, 40, 'shape=rounded');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/ellipse.gif', 40, 40, 'shape=ellipse');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/rhombus.gif', 40, 40, 'shape=rhombus');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/triangle.gif', 40, 40, 'shape=triangle');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/cylinder.gif', 40, 40, 'shape=cylinder');
addVertex('https://jgraph.github.io/mxgraph/javascript/examples/editors/images/actor.gif', 30, 40, 'shape=actor');
// read state on load
if(window.localStorage.graphState){
var doc = json2html(JSON.parse(localStorage.graphState));
var dec = new mxCodec(doc);
dec.decode(doc.documentElement, graph.getModel());
}
// save state on change
graph.getModel().addListener('change',function(){
var codec = new mxCodec();
window.localStorage.graphState = JSON.stringify(html2json(codec.encode(
graph.getModel()
)));
});
}
}
function addToolbarItem(graph, toolbar, prototype, image)
{
// Function that is executed when the image is dropped on
// the graph. The cell argument points to the cell under
// the mousepointer if there is one.
var funct = function(graph, evt, cell, x, y)
{
graph.stopEditing(false);
var vertex = graph.getModel().cloneCell(prototype);
vertex.geometry.x = x;
vertex.geometry.y = y;
graph.addCell(vertex);
graph.setSelectionCell(vertex);
}
// Creates the image which is used as the drag icon (preview)
var img = toolbar.addMode(null, image, function(evt, cell)
{
var pt = this.graph.getPointForEvent(evt);
funct(graph, evt, cell, pt.x, pt.y);
});
// Disables dragging if element is disabled. This is a workaround
// for wrong event order in IE. Following is a dummy listener that
// is invoked as the last listener in IE.
mxEvent.addListener(img, 'mousedown', function(evt)
{
// do nothing
});
// This listener is always called first before any other listener
// in all browsers.
mxEvent.addListener(img, 'mousedown', function(evt)
{
if (img.enabled == false)
{
mxEvent.consume(evt);
}
});
mxUtils.makeDraggable(img, graph, funct);
return img;
}
</script>
</head>
<!-- Calls the main function after the page has loaded. Container is dynamically created. -->
<body onload="main();" >
</body>
</html>
please help me thanks in advance!!!
Check out this CodePen link which has the modified version of the snippet you gave. In it, you can add new elements and change texts and see an updated json string representing the relationships in the graph: https://codepen.io/tien-q-nguyen2/pen/GaQXBO
I also edited the function a little from the first time I posted this answer.
Note: based on the expected output you put in the original question, there is only one parent per vertex element ({"id":1,"parent":0 <= in the example you gave), so if there are multiple nodes pointing to the same child , the child's parent property will only refer to the first parent's id. I can change the parent's property to be an array that can keep multiple parent's ids if you want.
function getNodesFrom(graph){
var cells = graph.getModel().cells;
var vertices = [], edges = [];
for (var key in cells) {
if (cells[key].isVertex()){
vertices.push(cells[key]);
}
else if (cells[key].isEdge()){
edges.push(cells[key]);
}
}
var simpleVertices = [], simpleEdges = [];
var newIndex = 0;
var newIndexOf = [];
vertices.forEach(function(vertex){
simpleVertices.push({id: newIndex, value: vertex.value});
newIndexOf[vertex.id] = newIndex++;
});
edges.forEach(function(edge){
if (edge.target === null || edge.source === null) return;
simpleEdges.push({
parentId: newIndexOf[edge.source.id],
childId: newIndexOf[edge.target.id],
value: edge.value
});
});
var edgesForParentIndex = [];
var edgesForChildIndex = [];
simpleEdges.forEach(function(edge){
if (edgesForParentIndex[edge.parentId] === undefined){
edgesForParentIndex[edge.parentId] = [];
}
edgesForParentIndex[edge.parentId].push(edge);
if (edgesForChildIndex[edge.childId] === undefined){
edgesForChildIndex[edge.childId] = [];
}
edgesForChildIndex[edge.childId].push(edge);
});
var nodes = [];
simpleVertices.forEach(function(vertex){
var node = {};
node.id = vertex.id;
if (edgesForChildIndex[node.id] === undefined){
node.parent = '#';
} else {
node.parent = edgesForChildIndex[node.id][0].parentId;
}
node.text = (vertex.value === undefined || vertex.value === null) ? '' : vertex.value;
node.child = [];
if (edgesForParentIndex[node.id] === undefined){
node.child.push({cid: null, connectionText: ""});
} else {
edgesForParentIndex[node.id].forEach(function(edge){
var text = (edge.value === undefined || edge.value === null) ? '' : edge.value;
node.child.push({cid: edge.childId, connectionText: text});
});
}
nodes.push(node);
});
return nodes;
}

chartist Uncaught TypeError: Cannot read property

I want to create a chartist line graph with data from my database, but when I try to draw it, I have a javascript error:
chartist.min.js:8 Uncaught TypeError: Cannot read property
Here is my code,
HTML page:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Graphique Vitesse</title>
<link rel="stylesheet" type="text/css" href="chartist.min.css"/>
<script src="jquery.js"></script>
<script src="chartist.min.js"></script>
<script type="text/javascript">
function test() {
var c=0;
var series = [];
for (var i = 80; i < 81; ++i) {
$.ajax({url: "test.php?id_cycliste="+i, success: function(result){
var i=0;
var ser = []
for (v of result){
alert("test1 " + v);
//alert("Salope"+v);
ser[i] = v.y;
++i;
alert(1);
}
alert(2)
series[c] = ser;
++c;
}});
//alert ("Tu va te prendre une calotte"+series.toString());
alert("test 2"+series.toString())
// $.ajax(("test.php?id_cycliste="+i), function (result) {
// var i=0;
// var ser = []
//
// for (v of result){
// alert("Salope"+v);
// ser[i] = v.y;
// ++i;
// alert(1);
// }
// alert(2)
// series[c] = ser;
// ++c;
// })
// alert ("Tu va te prendre une calotte"+series.toString());
}
var options = {
// Don't draw the line chart points
showPoint: false,
// Disable line smoothing
lineSmooth: false,
// X-Axis specific configuration
axisX: {
// We can disable the grid for this axis
showGrid: false,
// and also don't show the label
showLabel: false
},
// Y-Axis specific configuration
axisY: {
// Lets offset the chart a bit from the labels
offset: 60,
// The label interpolation function enables you to modify the values
// used for the labels on each axis. Here we are converting the
// values into million pound.
labelInterpolationFnc: function(value) {
return '$' + value + 'm';
}
}
};
// var data = {labels,series}
var data = {
// A labels array that can contain any sort of values
labels : [0,2,4,6,8,10,12,14,16],
// Our series array that contains series objects or in this case series data arrays
series
};
new Chartist.Line('.ct-chart', data, options);
}
test();
</script>
</head>
<body>
<h1> Bonjour </h1>
<div class="ct-chart ct-perfect-fourth"></div>
<div class="ct-chart"></div>
<div id="graphVitesse" style="height: 350px;"></div>
</body>
</html>
PHP page:
<?php
header('Content-Type: application/json');
$con = mysqli_connect("localhost","root","","veloinfospublic");
// Check connection
$id = $_GET["id_cycliste"];
if (mysqli_connect_errno($con))
{
echo "Failed to connect to DataBase: " . mysqli_connect_error();
}else
{
$data_points = array();
$result = mysqli_query($con, "SELECT Temps,Vitesse FROM releve where cycliste_id=".$id);
// var_dump ($result);
// while($row = mysqli_fetch_array($result))
// {
// $point = array("label" => $row['temps'] , "y" => $row['vitesse']);
// var_dump ($point);
//
//
// }
while ($row = $result->fetch_assoc()) {
$point = array("label" => $row['Temps'] , "y" => $row['Vitesse']);
array_push($data_points, $point);
}
echo json_encode($data_points, JSON_NUMERIC_CHECK);
}
mysqli_close($con);
?>
if I go to http://localhost/chartservice/test.php?id_cycliste=80
I have the following result:
[{"label":0,"y":37},{"label":2,"y":35},{"label":4,"y":5},{"label":6,"y":11},{"label":8,"y":23},{"label":10,"y":33},{"label":12,"y":27},{"label":14,"y":37}]
but if I go to the HTML page I have no graphics diplayed and I have the folloing JS error:
chartist.min.js:8 Uncaught TypeError: Cannot read property 'querySelectorAll' of nullc.createSvg # chartist.min.js:8d # chartist.min.js:8h # chartist.min.js:8
Have you found the problem? Can You help me please?
Thanks
I have solve the problem, I have just moved the script after the body
like that
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Graphique Vitesse</title>
<link rel="stylesheet" type="text/css" href="chartist.min.css"/>
<script src="jquery.js"></script>
<script src="chartist.min.js"></script>
</head>
<body>
<h1> Bonjour </h1>
<div class="ct-chart ct-perfect-fourth"></div>
<div class="ct-chart"></div>
<div id="graphVitesse" style="height: 350px;"></div>
</body>
<script type="text/javascript">
function test() {
var c=0;
var series = [];
for (var i = 80; i < 81; ++i) {
$.ajax({url: "test.php?id_cycliste="+i, success: function(result){
var i=0;
var ser = []
for (v of result){
alert("test1 " + v);
//alert("Salope"+v);
ser[i] = v.y;
++i;
alert(1);
}
alert(2)
series[c] = ser;
++c;
}});
//alert ("Tu va te prendre une calotte"+series.toString());
alert("test 2"+series.toString())
// $.ajax(("test.php?id_cycliste="+i), function (result) {
// var i=0;
// var ser = []
//
// for (v of result){
// alert("Salope"+v);
// ser[i] = v.y;
// ++i;
// alert(1);
// }
// alert(2)
// series[c] = ser;
// ++c;
// })
// alert ("Tu va te prendre une calotte"+series.toString());
}
var options = {
// Don't draw the line chart points
showPoint: false,
// Disable line smoothing
lineSmooth: false,
// X-Axis specific configuration
axisX: {
// We can disable the grid for this axis
showGrid: false,
// and also don't show the label
showLabel: false
},
// Y-Axis specific configuration
axisY: {
// Lets offset the chart a bit from the labels
offset: 60,
// The label interpolation function enables you to modify the values
// used for the labels on each axis. Here we are converting the
// values into million pound.
labelInterpolationFnc: function(value) {
return '$' + value + 'm';
}
}
};
// var data = {labels,series}
var data = {
// A labels array that can contain any sort of values
labels : [0,2,4,6,8,10,12,14,16],
// Our series array that contains series objects or in this case series data arrays
series
};
new Chartist.Line('.ct-chart', data, options);
}
test();
</script>
</html>

Sort array of images with mootools and javascript

I'm trying to sort an array of images by dragging and dropping them.
If the dragged image (cur) comes before the image I drop it on (next), I want I want the images up to next to move back one. Else, I want the images from next to cur-1 to move forward one.
As far as I can tell my logic is correct, but dragging backwards (next < cur) doesn't always work properly. Sometimes it places an image on top of another one, or at the end of the array, or extends the array by one.
My brain has gone numb, so help please...
The html/javascript,
<!doctype html>
<html>
<head>
<title>UI Test</title>
<script type="text/javascript" src="MooTools-Core-1.5.1.js"></script>
<script type="text/javascript" src="MooTools-More-1.5.1.js"></script>
<link rel="stylesheet" type="text/css" href="res/UI.css"/>
</head>
<body>
<p id="debug_area">debug area</p>
<script type="text/javascript">
//Areas and placeholders
//divs
var searchArea = new Element('div', {
id: 'search_area'
});
var resultsArea = new Element('div', {
id: 'results_area'
});
var resultsOverflow = new Element('div', {
id: 'results_overflow'
});
var pinnedArea = new Element('div', {
id: 'pinned_area'
});
var pinnedOverflow = new Element('div', {
id: 'pinned_overflow'
});
var timeweatherArea = new Element('div', {
id: 'timeweather_area'
});
var appArea = new Element('div', {
id: 'app_area'
});
var videoArea = new Element('div', {
id: 'video_area'
});
//THUMBNAIL STUFF
var numResults = 0;
var arrResults = [];
var numPinned = 0;
var arrPinned = [];
var playlist = [];
var drops = [];
drops.push(resultsArea);
drops.push(pinnedArea);
var reorderImages = function(array){
for(i=0;i<array.length;i++){
array[i].setStyle('top', 100*((i-(i%2))/2));
array[i].setStyle('left', 100*(i%2));
}
};
var images = [];
for(i=0;i<10;i++){
var image = new Element('img', {
id: 'image_'+i,
class: 'draggable',
src: 'res/vid/thumbs/'+(i+1)+'-thumb.jpeg',
alt: 'Image',
height: '100',
width: '100',
position: 'absolute',
styles:{
visibility: 'visible'
}
});
images.push(image);
arrResults.push(image);
var mouseX=0,mouseY=0;
image.makeDraggable({
droppables: drops,
container: searchArea,
onStart: function(draggable){
////$('debug_area').set('html', 'start: '+draggable.id);
},
onEnter: function(draggable, droppable){
////$('debug_area').set('html', 'entered '+droppable.id);
},
onLeave: function(draggable, droppable){
////$('debug_area').set('html', 'left '+droppable.id);
if(droppable.id == 'results_area'){
draggable.inject(searchArea);
draggable.setStyle('top', searchArea.get('top'));
draggable.setStyle('left', searchArea.get('left'));
}
},
onDrop: function(draggable, droppable){
////$('debug_area').set('html', 'dropped in '+droppable.id);
var string;
var val;
if(droppable){
string = draggable.id;
val = string.replace('image_', '').toInt();
}
if(droppable.id == 'pinned_area'){
if(arrResults.indexOf(draggable) != -1)
arrResults.erase(draggable);
if(arrPinned.indexOf(draggable) == -1){
arrPinned.push(draggable);
val = arrPinned.indexOf(draggable);
}
draggable.inject(pinnedOverflow);
draggable.setStyle('float', 'right');
reorderImages(arrResults);
reorderImages(arrPinned);
////$('debug_area').set('html', arrPinned.length +' / '+arrResults.length +' = '+ arrPinned.indexOf(draggable));
}else if(droppable.id == 'results_area'){
if(arrPinned.indexOf(draggable) != -1)
arrPinned.erase(draggable);
if(arrResults.indexOf(draggable) == -1){
arrResults.push(draggable);
val = arrResults.indexOf(draggable);
draggable.inject(resultsOverflow);
}else{
//code for sorting
var cur, next;
var x=draggable.getPosition().x, y=draggable.getPosition().y;
for(i=0;i<arrResults.length;i++){
var nextX = arrResults[i].getPosition().x, nextY = arrResults[i].getPosition().y;
if((x-x%100)/100 == (nextX-nextX%100)/100){
if((y-y%100)/100 == (nextY-nextY%100)/100){
cur = arrResults.indexOf(draggable);
next = i;
$('debug_area').set('html',arrResults[i].get('id')+' '+cur+' '+next+' '+arrResults.length);
if(cur < next){
for(j=cur+1;j<=next;j++){
var temp = arrResults[j];
arrResults[j-1] = temp;
}
arrResults[next] = draggable;
break;
}else if(cur > next){
for(j=next;j<cur;j++){
var temp = arrResults[j];
arrResults[j+1] = temp;
}
arrResults[next] = draggable;
break;
}
}
}
}
}
//draggable.setStyle('float', 'right');
reorderImages(arrResults);
reorderImages(arrPinned);
////$('debug_area').set('html', arrPinned.length +' / '+arrResults.length +' = '+ arrResults.indexOf(draggable));
}
}
});
image.setStyle('position', 'absolute');
image.setStyle('top', 100*((i-(i%2))/2));
image.setStyle('left', 100*(i%2));
}
resultsOverflow.adopt(images);
var refreshThumbs = function(){
var source;
for(i=0;i<arrResults.length;i++){
source = arrResults[i].get('src');
source = source.split('?');
arrResults[i].set('src', source[0]+'?'+ new Date().getTime());
}
for(i=0;i<arrPinned.length;i++){
source = arrPinned[i].get('src');
source = source.split('?');
arrPinned[i].set('src', source[0]+'?'+ new Date().getTime());
}
};
refreshThumbs.periodical(10000);
//MASTER AREA INJECTION
resultsOverflow.inject(resultsArea);
resultsArea.inject(searchArea);
pinnedOverflow.inject(pinnedArea);
pinnedArea.inject(searchArea);
searchArea.inject(appArea);
videoArea.inject(appArea);
appArea.inject(document.body);
window.addEvent('domready', function(){
});
window.addEvent('load', function(){
});
</script>
</body>
</html>
The css is fine (I think) but here it is anyway, http://pastebin.com/xQ8ZrRmw
Here's the JSFiddle, https://jsfiddle.net/L4tgh25a/
UPDATE 1:
Changing,
else if(cur > next){
for(j=next;j<cur;j++){
var temp = arrResults[j];
arrResults[j+1] = temp;
}
arrResults[next] = draggable;
break;
}
to,
else if(cur > next){
arrResults.splice(cur, 1);
arrResults.splice(next, 0, draggable);
break;
}
fixes the problem. Why? I'm quite sure my algorithm was correct (but not accounting for the beginning and end of the array, which doesn't matter because the problem happens in the middle anyway). Was my algorithm wrong or was it a javascript thing?

jquery html(array) doesn't insert all items in array

When I run the javascript code below, it load specified amount of images from Flickr.
By var photos = photoGroup.getPhotos(10) code, I get 10 images from cache.
Then, I can see the object has exactly 10 items by checking console.log(photos);
But actual image appeared on the page is less than 10 items...
I have no idea why this work this way..
Thank you in advance.
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script>
var PhotoGroup = function(nativePhotos, callback) {
var _cache = new Array();
var numberOfPhotosLoaded = 0;
var containerWidth = $("#contents").css('max-width');
var containerHeight = $("#contents").css('max-height');
$(nativePhotos).each(function(key, photo) {
$("<img src='"+"http://farm" + photo["farm"] + ".staticflickr.com/" + photo["server"] + "/" + photo["id"] + "_" + photo["secret"] + "_b.jpg"+"'/>")
.attr("alt", photo['title'])
.attr("data-cycle-title", photo['ownername'])
.load(function() {
if(this.naturalWidth >= this.naturalHeight) {
$(this).attr("width", containerWidth);
} else {
$(this).attr("height", containerHeight);
}
_cache.push(this);
if(nativePhotos.length == ++numberOfPhotosLoaded)
callback();
})
});
var getRandom = function(max) {
return Math.floor((Math.random()*max)+1);
}
this.getPhotos = function(numberOfPhotos) {
var photoPool = new Array();
var maxRandomNumber = _cache.length-1;
while(photoPool.length != numberOfPhotos) {
var index = getRandom(maxRandomNumber);
if($.inArray(_cache[index], photoPool))
photoPool.push(_cache[index]);
}
return photoPool;
}
}
var Contents = function() {
var self = this;
var contentTypes = ["#slideShowWrapper", "#video"];
var switchTo = function(nameOfContent) {
$(contentTypes).each(function(contentType) {
$(contentType).hide();
});
switch(nameOfContent) {
case("EHTV") :
$("#video").show();
break;
case("slideShow") :
$("#slideShowWrapper").show();
break;
default :
break;
}
}
this.startEHTV = function() {
switchTo("EHTV");
document._video = document.getElementById("video");
document._video.addEventListener("loadstart", function() {
document._video.playbackRate = 0.3;
}, false);
document._video.addEventListener("ended", startSlideShow, false);
document._video.play();
}
this.startSlideShow = function() {
switchTo("slideShow");
var photos = photoGroup.getPhotos(10)
console.log(photos);
$('#slideShow').html(photos);
}
var api_key = '6242dcd053cd0ad8d791edd975217606';
var group_id = '2359176#N25';
var flickerAPI = 'http://api.flickr.com/services/rest/?jsoncallback=?';
var photoGroup;
$.getJSON(flickerAPI, {
api_key: api_key,
group_id: group_id,
format: "json",
method: "flickr.groups.pools.getPhotos",
}).done(function(data) {
photoGroup = new PhotoGroup(data['photos']['photo'], self.startSlideShow);
});
}
var contents = new Contents();
</script>
</head>
<body>
<div id="slideShow"></div>
</body>
</html>
I fix your method getRandom() according to this article, and completely re-write method getPhotos():
this.getPhotos = function(numberOfPhotos) {
var available = _cache.length;
if (numberOfPhotos >= available) {
// just clone existing array
return _cache.slice(0);
}
var result = [];
var indices = [];
while (result.length != numberOfPhotos) {
var r = getRandom(available);
if ($.inArray(r, indices) == -1) {
indices.push(r);
result.push(_cache[r]);
}
}
return result;
}
Check full solution here: http://jsfiddle.net/JtDzZ/
But this method still slow, because loop may be quite long to execute due to same random numbers occurred.
If you care about performance, you need to create other stable solution. For ex., randomize only first index of your images sequence.

jQuery plugin DataTables: How to highlight the current search text?

I have started using the DataTables plugin (v1.6.2) for jQuery(v1.4.2), and I would like to ask you if you know a settings or a plugin that allow me to highlight the text used in search textbox on the filtered rows.
Thank you in advance
I would have to suggest the highlight plugin :)
I'm using this in about the same scenario right now, it's given me no issues thus far.
The usage is pretty simple:
$("#myTable").highlight($("#searchBox").val());
Just put the highlight CSS class in your stylesheet styles like you want and that's it:
.highlight { background-color: yellow }
I know that this question is now over 6 years old and the answers here may helped you at the time of asking. But for people still searching for this, there is a new plugin to integrate mark.js – a JavaScript keyword highlighter – into DataTables: datatables.mark.js.
Usage is as simple as:
$("table").DataTables({
mark: true
});
Here is an example: https://jsfiddle.net/julmot/buh9h2r8/
This is the cleanest way and also gives you options none of the given solutions offers you.
There's now an official DataTables blog article available.
You can use this function by coping this content :
jQuery.fn.dataTableExt.oApi.fnSearchHighlighting = function(oSettings) {
oSettings.oPreviousSearch.oSearchCaches = {};
oSettings.oApi._fnCallbackReg( oSettings, 'aoRowCallback', function( nRow, aData, iDisplayIndex, iDisplayIndexFull) {
// Initialize search string array
var searchStrings = [];
var oApi = this.oApi;
var cache = oSettings.oPreviousSearch.oSearchCaches;
// Global search string
// If there is a global search string, add it to the search string array
if (oSettings.oPreviousSearch.sSearch) {
searchStrings.push(oSettings.oPreviousSearch.sSearch);
}
// Individual column search option object
// If there are individual column search strings, add them to the search string array
if ((oSettings.aoPreSearchCols) && (oSettings.aoPreSearchCols.length > 0)) {
for (var i in oSettings.aoPreSearchCols) {
if (oSettings.aoPreSearchCols[i].sSearch) {
searchStrings.push(oSettings.aoPreSearchCols[i].sSearch);
}
}
}
// Create the regex built from one or more search string and cache as necessary
if (searchStrings.length > 0) {
var sSregex = searchStrings.join("|");
if (!cache[sSregex]) {
var regRules = "("
, regRulesSplit = sSregex.split(' ');
regRules += "("+ sSregex +")";
for(var i=0; i<regRulesSplit.length; i++) {
regRules += "|("+ regRulesSplit[i] +")";
}
regRules += ")";
// This regex will avoid in HTML matches
cache[sSregex] = new RegExp(regRules+"(?!([^<]+)?>)", 'ig');
}
var regex = cache[sSregex];
}
// Loop through the rows/fields for matches
jQuery('td', nRow).each( function(i) {
// Take into account that ColVis may be in use
var j = oApi._fnVisibleToColumnIndex( oSettings,i);
// Only try to highlight if the cell is not empty or null
if (aData[j]) {
// If there is a search string try to match
if ((typeof sSregex !== 'undefined') && (sSregex)) {
this.innerHTML = aData[j].replace( regex, function(matched) {
return "<span class='filterMatches'>"+matched+"</span>";
});
}
// Otherwise reset to a clean string
else {
this.innerHTML = aData[j];
}
}
});
return nRow;
}, 'row-highlight');
return this;
};
inside :
dataTables.search-highlight.js
an call it like this example:
<script type="text/javascript" src="jquery.dataTables.js"></script>
<script type="text/javascript" src="dataTables.search-highlight.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var oTable = $('#example').dataTable();
oTable.fnSearchHighlighting();
} );
</script>
and add this code to you css file:
.filterMatches{
background-color: #BFFF00;
}
<link href="https://cdn.datatables.net/plug-ins/1.10.13/features/mark.js/datatables.mark.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/jquery.mark.js"></script>
<script src="https://cdn.datatables.net/plug-ins/1.10.13/features/mark.js/datatables.mark.js"></script>
$("#tableId").dataTable({
mark: true
});
You can use the following add on
jQuery.fn.dataTableExt.oApi.fnSearchHighlighting = function(oSettings) {
// Initialize regex cache
oSettings.oPreviousSearch.oSearchCaches = {};
oSettings.oApi._fnCallbackReg( oSettings, 'aoRowCallback', function( nRow, aData, iDisplayIndex, iDisplayIndexFull) {
// Initialize search string array
var searchStrings = [];
var oApi = this.oApi;
var cache = oSettings.oPreviousSearch.oSearchCaches;
// Global search string
// If there is a global search string, add it to the search string array
if (oSettings.oPreviousSearch.sSearch) {
searchStrings.push(oSettings.oPreviousSearch.sSearch);
}
// Individual column search option object
// If there are individual column search strings, add them to the search string array
// searchTxt=($('#filter_input input[type="text"]')?$('#filter_input input[type="text"]').val():"");
var searchTxt = $('input[type="search"]').val();
// console.log("txt" + searchTxt);
if ((oSettings.aoPreSearchCols) && (oSettings.aoPreSearchCols.length > 0)) {
for (var i in oSettings.aoPreSearchCols) {
if (oSettings.aoPreSearchCols[i].sSearch) {
searchStrings.push(searchTxt);
}
}
}
// Create the regex built from one or more search string and cache as necessary
/*if (searchStrings.length > 0) {
var sSregex = searchStrings.join("|");
if (!cache[sSregex]) {
// This regex will avoid in HTML matches
cache[sSregex] = new RegExp("("+escapeRegExpSpecialChars(sSregex)+")(?!([^<]+)?>)", 'i');
}
var regex = cache[sSregex];
}*/
if (searchStrings.length > 0) {
var sSregex = searchStrings.join("|");
if (!cache[sSregex]) {
var regRules = "("
, regRulesSplit = sSregex.split(' ');
regRules += "("+ sSregex +")";
for(var i=0; i<regRulesSplit.length; i++) {
regRules += "|("+ regRulesSplit[i] +")";
}
regRules += ")";
// This regex will avoid in HTML matches
cache[sSregex] = new RegExp(regRules+"(?!([^<]+)?>)", 'ig');
}
var regex = cache[sSregex];
}
// Loop through the rows/fields for matches
jQuery('td', nRow).each( function(i) {
// Take into account that ColVis may be in use
var j = oApi._fnVisibleToColumnIndex( oSettings,i);
// Only try to highlight if the cell is not empty or null
// console.log("data "+ aData[j] + " j " + j);
// console.log("data 1 "+ nRow);
if (aData) {
// If there is a search string try to match
if ((typeof sSregex !== 'undefined') && (sSregex)) {
//console.log("here :: "+$(this).text());
this.innerHTML = $(this).text().replace( regex, function(matched) {
return "<span class='filterMatches'>"+matched+"</span>";
});
}
// Otherwise reset to a clean string
else {
this.innerHTML = $(this).text();//aData[j];
}
}
});
return nRow;
}, 'row-highlight');
return this;
};
This solution is working for me.
Note: Currently it does not support individual column filtering, but you just have to uncomment following in the code.
searchTxt=($('#filter_input input[type="text"]')?$('#filter_input input[type="text"]').val():"");
I have tested this with datatables 1.10.2 and jquery 1.9.2 version.
This add on have better feature for highlighting search text. if you have created datatable in a dialog , then on dialog reopen you need to reinitialize datatable.
In DatatableHighlighter.js
jQuery.fn.dataTableExt.oApi.fnSearchHighlighting = function(oSettings) {
// Initialize regex cache
oSettings.oPreviousSearch.oSearchCaches = {};
oSettings.oApi._fnCallbackReg( oSettings, 'aoRowCallback', function( nRow, aData, iDisplayIndex, iDisplayIndexFull) {
// Initialize search string array
var searchStrings = [];
var oApi = this.oApi;
var cache = oSettings.oPreviousSearch.oSearchCaches;
// Global search string
// If there is a global search string, add it to the search string array
if (oSettings.oPreviousSearch.sSearch) {
searchStrings.push(oSettings.oPreviousSearch.sSearch);
}
// Individual column search option object
// If there are individual column search strings, add them to the search string array
// searchTxt=($('#filter_input input[type="text"]')?$('#filter_input input[type="text"]').val():"");
var searchTxt = $('input[type="search"]').val();
// console.log("txt" + searchTxt);
if ((oSettings.aoPreSearchCols) && (oSettings.aoPreSearchCols.length > 0)) {
for (var i in oSettings.aoPreSearchCols) {
if (oSettings.aoPreSearchCols[i].sSearch) {
searchStrings.push(searchTxt);
}
}
}
// Create the regex built from one or more search string and cache as necessary
if (searchStrings.length > 0) {
var sSregex = searchStrings.join("|");
if (!cache[sSregex]) {
var regRules = "("
, regRulesSplit = sSregex.split(' ');
regRules += "("+ sSregex +")";
for(var i=0; i<regRulesSplit.length; i++) {
regRules += "|("+ regRulesSplit[i] +")";
}
regRules += ")";
// This regex will avoid in HTML matches
cache[sSregex] = new RegExp(regRules+"(?!([^<]+)?>)", 'ig');
//cache[sSregex] = new RegExp(regRules+"", 'ig');
}
var regex = cache[sSregex];
}
// Loop through the rows/fields for matches
jQuery('td', nRow).each( function(i) {
// Take into account that ColVis may be in use
var j = oApi._fnVisibleToColumnIndex( oSettings,i);
if (aData) {
// If there is a search string try to match
if ((typeof sSregex !== 'undefined') && (sSregex)) {
//For removing previous added <span class='filterMatches'>
var element = $(this);//convert string to JQuery element
element.find("span").each(function(index) {
var text = $(this).text();//get span content
$(this).replaceWith(text);//replace all span with just content
}).remove();
var newString = element.html();//get back new string
this.innerHTML = newString.replace( regex, function(matched) {
return "<span class='filterMatches'>"+matched+"</span>";
});
}
// Otherwise reset to a clean string
else {
//For removing previous added <span class='filterMatches'>
var element = $(this);//convert string to JQuery element
element.find("span").each(function(index) {
var text = $(this).text();//get span content
$(this).replaceWith(text);//replace all span with just content
}).remove();
var newString = element.html();
this.innerHTML = newString;//$(this).html()//$(this).text();
}
}
});
return nRow;
}, 'row-highlight');
return this;
};
and call it like this ....
$("#button").click(function() {
dTable = $('#infoTable').dataTable({"bPaginate": false,"bInfo" : false,"bFilter": true,"bSort":false, "autoWidth": false,"destroy": true,
"columnDefs": [
{ "width": "35%", "targets": 0 },
{ "width": "65%", "targets": 1 }
]});
$(".dataTables_filter input[type='search']").val('');
$("span[class='filterMatches']").contents().unwrap();
dTable.fnSearchHighlighting();
$("span[class='filterMatches']").contents().unwrap();
$("#AboutDialog").dialog('open');
});

Categories