I am trying to do a preview, from a database, and want the preview to be say, 20 words before and after the keyword. I can think of a couple of ways to do this, but seems it would work the server very hard.
One way is to break the data into a word array, with str_word_count(), then search the array, for the word index, and do the math, but it just seems like it would be hitting the server too hard.
Is there a better way of doing this?
"20" is just an example, and would trap for a length less than 20, so I know about trapping bad values. However, I do see other issues that may arise, such as, the keyword appears more than once, or if more than one search word is used, so I know it is not as easy as grab an array and do the math.
EDIT: It looks like the mod added link will do the trick. Will test now. Also for those that asked about the output:
Data: "this would be from the database, and got selected using full text query, the keyword used is 'selected'"
Output wanted: "database, and got SELECTED using full text".
I reckon the biggest drawback is querying those results, regardless of any string operations performed later on, either way it`s gonna cost you performance.
I'd go with javascript on this one, return the data from the PHP and have javascript find the words you`re looking for. It saves on your server's load by letting the browser figure it out.
But if you're dead set on using PHP, i`d go with what you've suggested, transform the string in an array of words and return the words based on the offset given.
in jQuery and javascript it could like like:
jQuery.ajax({
dataType: "json",
url: "path/to/script.php",
complete: response( response ){
// assuming we`re getting a json result
// in the following format:
// {
// "sentence": "This is my sentence with a word that should highlight the first and last 20 words..",
// "word": "hightlight"
// }
var offset = 20;
var output = createHightlight(response.sentence, response.word, offset);
}
});
function createHighlight(sentence, word, offset ){
var string = "";
var words = sentence.split(" ");
var index = words.indexOf(word);
offset = offset !== undefined ? offset : 20;
var start = 0, end = words.length;
if( index - offset >= 0){
start = index - offset;
}
if( index + offset < words.length){
end = index + offset;
}
for( var i = start; i <= end; i++ ){
string += words[i] + " ";
}
return string;
}
Related
I'm not sure exactly how to phrase this so I will show an example. I'm gathering input values in javascript and passing to my php page where I am trying to insert those values in a database.
Instead of inserting separate values it is inserting the entire string.
Part of my javascript below:
var form = document.forms[0];
var txtS = form["bulletlabels"];
var len = txtS.length;
var bulletlabels = "";
for(i=0;i<len;i++) {
bulletlabels += '"'+[i]+'_'+(txtS[i].value)+'_label",';
}
when I do an alert(bulletlabels); I get this:
"0_Lot Size_label","1_Rooms_label","2_Bathrooms_label","3_Basement_label",
On my php page I have:
$bulletlabels = array($_POST['bulletlabels']);
$length = count($bulletlabels);
for ($i = 0; $i < $length; $i++) {
mysqli_query($con,"UPDATE bullets SET bullettitle = '".$bulletlabels[$i]."' WHERE bulletrow = ($i+1)");
}
This inserts the below string into the database on ONE Row which is not the desired effect:
"0_Lot Size_label","1_Rooms_label","2_Bathrooms_label","3_Basement_label",
But here is the key to my confusion - if I manually type the string in, it inserts onto individual database rows as desired.
This inserts values individually as desired when typed manually:
$bulletlabels = array("0_Lot Size_label","1_Rooms_label","2_Bathrooms_label","3_Basement_label",);
Does NOT work and inserts the full concatenated string:
$bulletlabels = array($_POST['bulletlabels']);
Hope I explained well enough - arrays elude me.
EDIT:
Fix for the trailing comma:
var delim = "";
for(i=0;i<len;i++) {
bulletlabels += delim+[i]+'_'+(txtS[i].value)+'_label';
delim = ",";
}
Reference link for trailing comma fix:
Can you use a trailing comma in a JSON object?
Try changing the following line:
$bulletlabels = array($_POST['bulletlabels']);
to
$bulletlabels = explode(',', $_POST['bulletlabels']);
Also do not add quotes in your javascript:
bulletlabels += '"'+[i]+'_'+(txtS[i].value)+'_label",';
should be
bulletlabels += [i]+'_'+(txtS[i].value)+'_label,';
Explanation:
Currently, $bulletlabels is an array with one element, and this element is the following string: "0_Lot Size_label","1_Rooms_label","2_Bathrooms_label","3_Basement_label",. However, you want to have an array with several strings. That's why you need to use the explode function to convert it into a proper array.
Note:
Make sure not to include , in the label names, as it will break with this implementation. If you need to be able to use , too, you should use json functions.
there. I'm having a problem with creating arrays in certain conditions in php, i'll try to explain. Here's my code:
for ($i = 1; $i < $tamanho_array_afundamento; $i++) {
if ($array_afundamento[$i] - $array_afundamento[$i - 1] > 1) {
$a = $array_afundamento[$i - 1];
$con->query('CREATE TABLE IF NOT EXISTS afunda_$a
SELECT (L1_forma_tensao_max + L1_forma_tensao_min)/2 as L1_forma_tensao, (L2_forma_tensao_max + L2_forma_tensao_min)/2 as L2_forma_tensao, (L3_forma_tensao_max + L3_forma_tensao_min)/2 as L3_forma_tensao
FROM afundamento
WHERE id > $prevNum AND id < $a');
$tabelas_intervalos_afunda1 = ($con->query("SELECT * FROM afunda_$a");
while ($row = $tabelas_intervalos_afunda->fetch(PDO::FETCH_ASSOC)) {
$array_forma_onda_fase1_afund[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund[] = $row['L3_forma_tensao'];
}
$prevNum = $a;
}
}
So as u can see, i have an if statement in a for loop, what i'm wishing to do is to create
one set of:
{
$array_forma_onda_fase1_afund[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund[] = $row['L3_forma_tensao'];
}
every time the if statement is runned. I was trying replacing this in the original code:
{
$array_forma_onda_fase1_afund_$a[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund_$a[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund_$a[] = $row['L3_forma_tensao'];
}
so as $a is changed everytime the if statement is accessed, i could have a different set of these arrays for everytime the if statement is accessed, but php doesn't accept this and i wouldn't have a very good result, though if i can reach it i would be pleased.
But my goal is to get:
{
$array_forma_onda_fase1_afund_1[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund_1[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund_1[] = $row['L3_forma_tensao'];
}
{
$array_forma_onda_fase1_afund_2[] = $row['L1_forma_tensao'];
$array_forma_onda_fase2_afund_2[] = $row['L2_forma_tensao'];
$array_forma_onda_fase3_afund_2[] = $row['L3_forma_tensao'];
}
...
where the last number represents the array retrieved for the n-th time the if statement runned. Does someone have a tip for it?
Thanks in advance! Would appreciate any help.
EDIT
As asked, my real world terms is as follows:
I have a table from which i need to take all the data that is inside a given interval. BUT, there's a problem, my data is a sine function whose amplitude may change indefinite times (the data bank is entered by the user) and, when the amplitude goes inside that interval, i need to make some operations like getting the least value achieved while the data was inside that interval and some other parameters, for each interval separately, (That's why i created all those tables.) and count how many times it happpened.
So, in order to make one of the operations, i need an array with the data for each time the databank entered by the user goes in that interval (given by the limits of the create query.).
If i were not clear, just tell me please!
EDIT 2
Here's the image of part of the table i'm working with:
http://postimg.org/image/5vegnk043/
so, when the sine gets inside the interval i need, it can be seen by the L1_RMS column, who accuses it, so it's when i need to get the interval data until it gets outside the interval. But it may happens as many times as this table entered by the user brings it on and we need to bear in mind that i need all the intervals separately to deal with the data of each one.
Physics uh?
You can do what you wanted with the arrays, it's not pretty, but it's possible.
You can dynamically name your arrays with the _$a in the end, Variables variables, such as:
${"array_forma_onda_fase3_afund_" . $a}[] = "fisica é medo";
If I have a string of HTML, maybe like this...
<h2>Header</h2><p>all the <span class="bright">content</span> here</p>
And I want to manipulate the string so that all words are reversed for example...
<h2>redaeH</h2><p>lla eht <span class="bright">tnetnoc</span> ereh</p>
I know how to extract the string from the HTML and manipulate it by passing to a function and getting a modified result, but how would I do so whilst retaining the HTML?
I would prefer a non-language specific solution, but it would be useful to know php/javascript if it must be language specific.
Edit
I also want to be able to manipulate text that spans several DOM elements...
Quick<em>Draw</em>McGraw
warGcM<em>warD</em>kciuQ
Another Edit
Currently, I am thinking to somehow replace all HTML nodes with a unique token, whilst storing the originals in an array, then doing a manipulation which ignores the token, and then replacing the tokens with the values from the array.
This approach seems overly complicated, and I am not sure how to replace all the HTML without using REGEX which I have learned you can go to the stack overflow prison island for.
Yet Another Edit
I want to clarify an issue here. I want the text manipulation to happen over x number of DOM elements - so for example, if my formula randomly moves letters in the middle of a word, leaving the start and end the same, I want to be able to do this...
<em>going</em><i>home</i>
Converts to
<em>goonh</em><i>gmie</i>
So the HTML elements remain untouched, but the string content inside is manipulated (as a whole - so goinghome is passed to the manipulation formula in this example) in any way chosen by the manipulation formula.
If you want to achieve a similar visual effect without changing the text you could cheat with css, with
h2, p {
direction: rtl;
unicode-bidi: bidi-override;
}
this will reverse the text
example fiddle: http://jsfiddle.net/pn6Ga/
Hi I came to this situation long time ago and i used the following code. Here is a rough code
<?php
function keepcase($word, $replace) {
$replace[0] = (ctype_upper($word[0]) ? strtoupper($replace[0]) : $replace[0]);
return $replace;
}
// regex - match the contents grouping into HTMLTAG and non-HTMLTAG chunks
$re = '%(</?\w++[^<>]*+>) # grab HTML open or close TAG into group 1
| # or...
([^<]*+(?:(?!</?\w++[^<>]*+>)<[^<]*+)*+) # grab non-HTMLTAG text into group 2
%x';
$contents = '<h2>Header</h2><p>the <span class="bright">content</span> here</p>';
// walk through the content, chunk, by chunk, replacing words in non-NTMLTAG chunks only
$contents = preg_replace_callback($re, 'callback_func', $contents);
function callback_func($matches) { // here's the callback function
if ($matches[1]) { // Case 1: this is a HTMLTAG
return $matches[1]; // return HTMLTAG unmodified
}
elseif (isset($matches[2])) { // Case 2: a non-HTMLTAG chunk.
// declare these here
// or use as global vars?
return preg_replace('/\b' . $matches[2] . '\b/ei', "keepcase('\\0', '".strrev($matches[2])."')",
$matches[2]);
}
exit("Error!"); // never get here
}
echo ($contents);
?>
Parse the HTML with something that will give you a DOM API to it.
Write a function that loops over the child nodes of an element.
If a node is a text node, get the data as a string, split it on words, reverse each one, then assign it back.
If a node is an element, recurse into your function.
could use jquery?
$('div *').each(function(){
text = $(this).text();
text = text.split('');
text = text.reverse();
text = text.join('');
$(this).text(text);
});
See here - http://jsfiddle.net/GCAvb/
I implemented a version that seems to work quite well - although I still use (rather general and shoddy) regex to extract the html tags from the text. Here it is now in commented javascript:
Method
/**
* Manipulate text inside HTML according to passed function
* #param html the html string to manipulate
* #param manipulator the funciton to manipulate with (will be passed single word)
* #returns manipulated string including unmodified HTML
*
* Currently limited in that manipulator operates on words determined by regex
* word boundaries, and must return same length manipulated word
*
*/
var manipulate = function(html, manipulator) {
var block, tag, words, i,
final = '', // used to prepare return value
tags = [], // used to store tags as they are stripped from the html string
x = 0; // used to track the number of characters the html string is reduced by during stripping
// remove tags from html string, and use callback to store them with their index
// then split by word boundaries to get plain words from original html
words = html.replace(/<.+?>/g, function(match, index) {
tags.unshift({
match: match,
index: index - x
});
x += match.length;
return '';
}).split(/\b/);
// loop through each word and build the final string
// appending the word, or manipulated word if not a boundary
for (i = 0; i < words.length; i++) {
final += i % 2 ? words[i] : manipulator(words[i]);
}
// loop through each stored tag, and insert into final string
for (i = 0; i < tags.length; i++) {
final = final.slice(0, tags[i].index) + tags[i].match + final.slice(tags[i].index);
}
// ready to go!
return final;
};
The function defined above accepts a string of HTML, and a manipulation function to act on words within the string regardless of if they are split by HTML elements or not.
It works by first removing all HTML tags, and storing the tag along with the index it was taken from, then manipulating the text, then adding the tags into their original position in reverse order.
Test
/**
* Test our function with various input
*/
var reverse, rutherford, shuffle, text, titleCase;
// set our test html string
text = "<h2>Header</h2><p>all the <span class=\"bright\">content</span> here</p>\nQuick<em>Draw</em>McGraw\n<em>going</em><i>home</i>";
// function used to reverse words
reverse = function(s) {
return s.split('').reverse().join('');
};
// function used by rutherford to return a shuffled array
shuffle = function(a) {
return a.sort(function() {
return Math.round(Math.random()) - 0.5;
});
};
// function used to shuffle the middle of words, leaving each end undisturbed
rutherford = function(inc) {
var m = inc.match(/^(.?)(.*?)(.)$/);
return m[1] + shuffle(m[2].split('')).join('') + m[3];
};
// function to make word Title Cased
titleCase = function(s) {
return s.replace(/./, function(w) {
return w.toUpperCase();
});
};
console.log(manipulate(text, reverse));
console.log(manipulate(text, rutherford));
console.log(manipulate(text, titleCase));
There are still a few quirks, like the heading and paragraph text not being recognized as separate words (because they are in separate block level tags rather than inline tags) but this is basically a proof of method of what I was trying to do.
I would also like it to be able to handle the string manipulation formula actually adding and removing text, rather than replacing/moving it (so variable string length after manipulation) but that opens up a whole new can of works I am not yet ready for.
Now I have added some comments to the code, and put it up as a gist in javascript, I hope that someone will improve it - especially if someone could remove the regex part and replace with something better!
Gist: https://gist.github.com/3309906
Demo: http://jsfiddle.net/gh/gist/underscore/1/3309906/
(outputs to console)
And now finally using an HTML parser
(http://ejohn.org/files/htmlparser.js)
Demo: http://jsfiddle.net/EDJyU/
You can use a setInterval to change it every ** time for example:
const TITTLE = document.getElementById("Tittle") //Let's get the div
setInterval(()=> {
let TITTLE2 = document.getElementById("rotate") //we get the element at the moment of execution
let spanTittle = document.createElement("span"); // we create the new element "span"
spanTittle.setAttribute("id","rotate"); // attribute to new element
(TITTLE2.textContent == "TEXT1") // We compare wich string is in the div
? spanTittle.appendChild(document.createTextNode(`TEXT2`))
: spanTittle.appendChild(document.createTextNode(`TEXT1`))
TITTLE.replaceChild(spanTittle,TITTLE2) //finally, replace the old span for a new
},2000)
<html>
<head></head>
<body>
<div id="Tittle">TEST YOUR <span id="rotate">TEXT1</span></div>
</body>
</html>
Ok so what i want to be able to do is to perform a suggestive style search using the contents of an array instead of a doing a mySQL database query on every keyup.
So imagine a javascript object or array that is full of people's names:
var array = (jack,tom,john,sarah,barry,...etc);
I want to then query the contents of this array based on what the user has typed into the input box so far. So if they have typed 'j',both jack and john will be pulled out of the array.
I know this is possible via php mysql and ajax calls, but for reason of optimization I would like to be able to query the js array instead.
Hope someone can help me with this!
W.
as the name suggests, this finds elements of an array starting with the given string s.
Array.prototype.findElementsStartingWith = function(s) {
var r = [];
for(var i = 0; i < this.length; i++)
if(this[i].toString().indexOf(s) === 0)
r.push(this[i]);
return r;
}
// example
a = ["foo", "bar", "fooba", "quu", "foooba"];
console.log(a.findElementsStartingWith("fo"))
the rest is basically the same as in ajax-based scripts.
http://wwwo.google.com?q=autosuggest+using+javascript
AJAX calls fetch the contents from another serverside script files. You already have your data in the JS. Read a AJAX tutorial doing this. Then, just remove the parts where AJAX calls are made and replace it with your array's contents, and you're good to go.
I ended up using the following function to build my AJAX free instant search bar:
Example JS object being searched:
var $members = {
"123":{firstname:"wilson", lastname:"page", email:"wilpage#blueyonder.co.uk"},
"124":{firstname:"jamie", lastname:"wright", email:"jamie#blueyonder.co.uk"}
}
Example of function to search JS object:
$membersTab.find('.searchWrap input').keyup(function(){
var $term = $(this).val(),
$faces = $membersTab.find('.member'),
$matches = [];
if($term.length > 0){
$faces.hide();
$.each($members,function(uID,details){
$.each(details,function(detail,value){
if(value.indexOf($term) === 0){//if string matches term and starts at the first character
$faces.filter('[uID='+uID+']').show();
}
});
});
}else{
$faces.show();
}
});
It shows and hides users in a list if they partially match the entered search term.
Hope this helps someone out as I was clueless as to how to do this at first!
W.
how do i write a function in javascript that can get the current url eg:
http://www.blahblah.com/apps/category.php?pg=1&catId=3021
and depending on a user selection choice, appends another parameter to the url like:
http://localhost/buyamonline/apps/category.php?pg=1&catId=3021&limit=5
but heres the catch:
Everytime the user selects a diff choice, I dont want to keep appending stuff like
http://localhost/buyamonline/apps/category.php?pg=1&catId=3021&limit=5&limit=10 and so on.
I want to always replace add it if there is no limit parameter or replace the value if there is one.
I was trying to accomplish this using sprintf but failed.
i was doing like so:
var w = document.mylimit.limiter.selectedIndex;
var url_add = document.mylimit.limiter.options[w].value;
var loc = window.location.href;
window.location.href = sprintf(loc+"%s="+%s, "&limit", url_add);
Updated with regular expression solution implemented in JS.
You can use a regular expression using JavaScript replace() Method
You can use build the entire url each time rather than just appending a parameter
You can parse the url into it's parts before appending the parameter
Which would you prefer?
For #1: The following should do the trick. Note though, there are issues with using regular expressions for parsing urls. (Ref: stackoverflow.com/questions/1842681/…)
<script type="text/javascript">
var pattern = "&limit(\=[^&]*)?(?=&|$)|^foo(\=[^&]*)?(&|$)";
var modifiers = "";
var txt=new RegExp(pattern,modifiers);
var str="http://localhost/buyamonline/apps/category.php?pg=1&catId=3021&limit=5";
document.write(str+"<br/>");
var replacement = "&limit=10";
document.write(str.replace(txt, replacement));
</script>
Below you can find my sprintf implementation which you can use it in your JS code to achieve what you need. It works almost like the C++/Java/PHP sprintf function with some limitations: the format specifiers are written like %1 and does not support the typed format specifiers (like %d, %s, %.2f, etc).
String.prototype.sprintf = function() {
var matches,result = this, p = /%(\d)/g;
while (matches = p.exec(result)) {
result = result.replace(matches[0], arguments[parseInt(matches[1]) - 1]);
}
return result;
};
Syntax:
format.sprintf(arg1,arg2,...);
The format string is composed of zero or more format specifiers that follows this prototype:
a % followed by argument index, where the first argument has index 1.
The arg1, arg2, ... are the variable strings which will replace the format specifiers.
Example: 'The quick %1 fox jumps over the %2 dog'.sprintf('brown','lazy');
Usage example:
var str = 'The size of %1 (%2) exceeds the %3 (%4).';
console.log(str.sprintf('myfile.txt', '100MB', 'max. allowed size', '75MB'));
Output:
The size of myfile.txt (100MB) exceeds the max. allowed size (75MB).
Note: If you need a robust sprintf function then check the sprintf for JavaScript.