Imitate Google suggest with AJAX and PHP - php

I want to imitate Google suggest with the following code, which means:
step 1: When user types in search box, the query string will be processed by a server php file and query suggestion string is returned(using Ajax object).
step 2:When user clicks on a query suggestion, it will fill into the search box (autocomplete).
Step 1 is achieved while step 2 is not. I think the problem lies in the .click() method (I use .live() later, but it's still not working). My intention is to use .live() or .click() binding a onclick event to the dynamically created <li> element. Any idea?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script src="jquery-1.4.2.js">
</script>
<style>
#search,#suggest,ul,li{margin: 0; padding:0; width: 200px;}
ul{ list-style-type: none;}
.border{border: solid red 1px; }
</style>
<p>My first language is:</p>
<input type="text" width="200px" id="search" onkeyup="main(this.value)" value="" />
<ul id="suggest"></ul>
<script type="text/javascript">
$(function main(str)
{ //binding any forthcoming li element click event to a function
$('li').live('click', function(){ $("#search").val(array[i]);});
//setup Ajax object
var request=new XMLHttpRequest();
request.open("GET","language.php?q="+str,true)
//core function
request.onreadystatechange=function()
{
if ( request.readyState==4 && request.status==200)
{ if (str=="") {$('li').remove(); $('ul').removeClass('border');return;}
$('li').remove();
reply=request.responseText.split(",");
for (i=0;i<reply.length;i++)
{
//create HTML element of <li>
$('#suggest').append($('<li>',{id: 'li'+i, html: reply[i]}));
//style ul
$('ul').addClass('border');
}
}
}
request.send();
})
</script>
PHP:
<?php
$q=$_GET[q];
$a[]='english';
$a[]='chinese';
$a[]='japanese';
$a[]='eeeeee';
//lookup all hints from array if length of q>0
if (strlen($q) > 0)
{
$hint="";
for($i=0; $i<count($a); $i++)
{
if (strtolower($q)==strtolower(substr($a[$i],0,strlen($q))))
{
if ($hint=="")
{
$hint=$a[$i];
}
else
{
$hint=$hint." , ".$a[$i];
}
}
}
}
// Set output to "no suggestion" if no hint were found
// or to the correct values
if ($hint == "")
{
$response="no suggestion";
}
else
{
$response=$hint;
}
//output the response
echo $response;
?>

You're looking for jQuery Autocomplete.

You're correct about which line is the problem. You're missing the # to search by ID.
$('li'+i).click(function(){ $("#search").html(array[i]);});
should be
$('#li'+i).click(function(){ $("#search").html(array[i]);});
There are much cleaner ways to do this, however, that don't require a re-query of the document to attach this handler. I concur fully with the suggestion to use a plugin.

Also, you might want to wait for the user to be idle. This prevents too many round-trips. This would mean writing something like:
$("input").keyUp(function(e) {
clearTimeout(updater);
updater = setTimeout(whenReady, 200);
}
function whenReady() {
// update the search box here...
}

I went through your code and there are few issues in it.
1) If you want to bind click event on dynamically created elements then you should use .live('click', function(){}) event binder. This jQuery function will bind click event on the selector which will be created later on in the code dynamically so li elements that are coming from the server will automatically be binded to the click event if you write live() event on document ready function. Read docs.
Here is the sample code
<script>
$(function() {
$("#suggest li").live('click', function() {
$("#search").val($(this).text()); // li inner html contains text that needs to put into search box
alert($(this).text()); // or alert(array[i]); in your code
//c what is the out put of above code. better if you change name of an array
});
});
</script>
Also text input elements values are fetch using .val() function instead of .html function in your code $("#search").html(array[i]);
regards
Ayaz Alavi

If you want your application to work correctly, you should also consider to cache the response, in case of backspace for instance.

Related

multi image select and print selected images using jquery

i have image set div tag like below:
function printImg() {
pwin = window.open(document.getElementById("mainImg").src,"_blank");
window.print();
}
$(function () {
$("#gallery > img").click(function () {
if ($(this).data('selected')) {
$(this).removeClass('selected');
$(this).data('selected', false);
} else {
$(this).addClass('selected');
$(this).data('selected', true);
}
});
var selectedImageArray = [];
$('#gallery > img').each(function () {
if ($(this).data('selected')) {
selectedImageArray.print(this);
}
});
window.onafterprint = function(){
window.location.reload(true);
}
});
img.selected {
border: 3px solid green;
}
img:hover {
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="gallery" id="gallery">
<img name=imgqr[] id="mainImg" src="data:image/png;base64, {!! base64_encode(QrCode::format('png')->size(180)->generate($user->emp_code[$i])) !!} " width="100"; height="80"; >{{$user->emp_first_name}} {{$user->emp_last_name}} {{!!($user->dpt_name)!!}}</td></tr>
</div>
<input class="printMe" type="button" onclick="printImg()" value="printMe" />
i need to select image when user click on it, i added the script for this and it working, but i click print button it doesnt print qrcode image ,in meantime is printing whole page.
I also need check if image is selected and pass through array value to print seleted images +data name.
Window.print() will always print the entire current window. You could bypass this by adding the selected images to a pop up and then print that pop up.
popup = window.open();
popup.document.write("imagehtml");
popup.focus(); //required for IE
popup.print();
You can do this one window for one photo but ofcourse you can also add multiple photo's to one screen and then print it.
Your second question asks for an array with the selected images. Because you use jQuery you can just get them by
allSelectedImages = $('.selected');
You can loop that array en call the function .data() on it to get all data attributes!
Hope this helps!
You're calling print on the main window, call print from the window you opened
function printImg() {
pwin = window.open(document.getElementById("mainImg").src,"_blank");
pwin.print();
}
I do not think if there is any problem with your codes,
try this and let me know
Firefox :
Google Chrome:

Don't display a button while file exists on server

I'm trying to display a download button on an HTML page only when a specific file on the web server is deleted. I thought I'd use a CSS display: none; then a PHP script with a while loop that'd look like this :
while (file_exists("/aaa/file.txt")) {
sleep(5);
}
//set display property of the invisibleLink class to block and continue
The thing is I don't know how to do this last step and every thread I've seen about modifying CSS with PHP doesn't work with my use case.
PHP executes before anything is displayed on the screen, so you are probably not going to be able to do that: the code would simply sleep for 5 and then continue with generating the rest of the html before displaying to the user.
What you might want to do instead is mark the button as display: none and then when the page is done loading have a js function that calls a php page that returns whether the file exists or not. Have the js function loop until the php page says the file is gone, then have the js function display the button and stop looping.
<button type="button" id="test_btn" style="display: none;">Download</button>
<script type="text/javascript">
$(document).ready(function () {
checkFile();
function checkFile() {
$.ajax({
url: '/path/to/file_checker.php',
type: 'GET',
success: function (data) {
if (data === "deleted") { // or whatever you want the response to be
$('#test_btn').show();
}
else {
checkFile(); // you can add a setTimeout if you don't want this running too often
}
}
});
}
}
</script>
Then your file checker php can be something similar to what you had:
if (file_exists("/aaa/file.txt")) {
echo "exists";
}
else {
echo "deleted";
}
Just build the button and hide it with a class like this:
<style>
.hidden{ display:none;}
</style>
<?php
if(!file_exists("path") ){ $class = "hidden" }
echo "<input type='button' class='$class' name='stuff'>woo</button>";
?>

If Safari does not support the require attribute for inputs, how can I require a few specific inputs in my form? [duplicate]

I have tried following code for make the required field to notify the required field but its not working in safari browser.
Code:
<form action="" method="POST">
<input required />Your name:
<br />
<input type="submit" />
</form>
Above the code work in firefox. http://jsfiddle.net/X8UXQ/179/
Can you let me know the javascript code or any workarround? am new in javascript
Thanks
Safari, up to version 10.1 from Mar 26, 2017, doesn't support this attribute, you need to use JavaScript.
This page contains a hacky solution, that should add the desired functionality: http://www.html5rocks.com/en/tutorials/forms/constraintvalidation/#toc-safari
HTML:
<form action="" method="post" id="formID">
<label>Your name: <input required></label><br>
<label>Your age: <input required></label><br>
<input type="submit">
</form>
JavaScript:
var form = document.getElementById('formID'); // form has to have ID: <form id="formID">
form.noValidate = true;
form.addEventListener('submit', function(event) { // listen for form submitting
if (!event.target.checkValidity()) {
event.preventDefault(); // dismiss the default functionality
alert('Please, fill the form'); // error message
}
}, false);
You can replace the alert with some kind of less ugly warning, like show a DIV with error message:
document.getElementById('errorMessageDiv').classList.remove("hidden");
and in CSS:
.hidden {
display: none;
}
and in HTML:
<div id="errorMessageDiv" class="hidden">Please, fill the form.</div>
The only drawback to this approach is it doesn't handle the exact input that needs to be filled. It would require a loop accross all inputs in the form and checking the value (and better, check for "required" attribute presence).
The loop may look like this:
var elems = form.querySelectorAll("input,textarea,select");
for (var i = 0; i < elems.length; i++) {
if (elems[i].required && elems[i].value.length === 0) {
alert('Please, fill the form'); // error message
break; // show error message only once
}
}
If you go with jQuery then below code is much better. Just put this code bottom of the jquery.min.js file and it works for each and every form.
Just put this code on your common .js file and embed after this file jquery.js or jquery.min.js
$("form").submit(function(e) {
var ref = $(this).find("[required]");
$(ref).each(function(){
if ( $(this).val() == '' )
{
alert("Required field should not be blank.");
$(this).focus();
e.preventDefault();
return false;
}
}); return true;
});
This code work with those browser which does not support required (html5) attribute
Have a nice coding day friends.
I had the same problem with Safari and I can only beg you all to take a look at Webshim!
I found the solutions for this question and for this one very very useful, but if you want to "simulate" the native HTML5 input validation for Safari, Webshim saves you a lot of time.
Webshim delivers some "upgrades" for Safari and helps it to handle things like the HMTL5 datepicker or the form validation. It's not just easy to implement but also looks good enough to just use it right away.
Also useful answer on SO for initial set up for webshim here! Copy of the linked post:
At this time, Safari doesn't support the "required" input attribute. http://caniuse.com/#search=required
To use the 'required' attribute on Safari, You can use 'webshim'
1 - Download webshim
2 - Put this code :
<head>
<script src="js/jquery.js"></script>
<script src="js-webshim/minified/polyfiller.js"></script>
<script>
webshim.activeLang('en');
webshims.polyfill('forms');
webshims.cfg.no$Switch = true;
</script>
</head>
I have built a solution on top of #Roni 's one.
It seems Webshim is deprecating as it won't be compatible with jquery 3.0.
It is important to understand that Safari does validate the required attribute. The difference is what it does with it. Instead of blocking the submission and show up an error message tooltip next to the input, it simply let the form flow continues.
That being said, the checkValidity() is implemented in Safari and does returns us false if a required filed is not fulfilled.
So, in order to "fix it" and also show an error message with minimal intervention (no extra Div's for holding error messages) and no extra library (except jQuery, but I am sure it can be done in plain javascript)., I got this little hack using the placeholder to show standard error messages.
$("form").submit(function(e) {
if (!e.target.checkValidity()) {
console.log("I am Safari"); // Safari continues with form regardless of checkValidity being false
e.preventDefault(); // dismiss the default functionality
$('#yourFormId :input:visible[required="required"]').each(function () {
if (!this.validity.valid) {
$(this).focus();
$(this).attr("placeholder", this.validationMessage).addClass('placeholderError');
$(this).val(''); // clear value so it shows error message on Placeholder.
return false;
}
});
return; // its invalid, don't continue with submission
}
e.preventDefault(); // have to add it again as Chrome, Firefox will never see above
}
I found a great blog entry with a solution to this problem. It solves it in a way that I am more comfortable with and gives a better user experience than the other suggestions here. It will change the background color of the fields to denote if the input is valid or not.
CSS:
/* .invalid class prevents CSS from automatically applying */
.invalid input:required:invalid {
background: #BE4C54;
}
.invalid textarea:required:invalid {
background: #BE4C54;
}
.invalid select:required:invalid {
background: #BE4C54;
}
/* Mark valid inputs during .invalid state */
.invalid input:required:valid {
background: #17D654 ;
}
.invalid textarea:required:valid {
background: #17D654 ;
}
.invalid select:required:valid {
background: #17D654 ;
}
JS:
$(function () {
if (hasHtml5Validation()) {
$('.validate-form').submit(function (e) {
if (!this.checkValidity()) {
// Prevent default stops form from firing
e.preventDefault();
$(this).addClass('invalid');
$('#status').html('invalid');
}
else {
$(this).removeClass('invalid');
$('#status').html('submitted');
}
});
}
});
function hasHtml5Validation () {
return typeof document.createElement('input').checkValidity === 'function';
}
Credit: http://blueashes.com/2013/web-development/html5-form-validation-fallback/
(Note: I did extend the CSS from the post to cover textarea and select fields)
I use this solution and works fine
$('#idForm').click(function(e) {
e.preventDefault();
var sendModalForm = true;
$('[required]').each(function() {
if ($(this).val() == '') {
sendModalForm = false;
alert("Required field should not be blank."); // or $('.error-message').show();
}
});
if (sendModalForm) {
$('#idForm').submit();
}
});
The new Safari 10.1 released Mar 26, 2017, now supports the "required" attribute.
http://caniuse.com/#search=required
You can add this event handler to your form:
// Chrome and Firefox will not submit invalid forms
// so this code is for other browsers only (e.g. Safari).
form.addEventListener('submit', function(event) {
if (!event.target.checkValidity()) {
event.preventDefault();
var inputFields = form.querySelectorAll('input');
for (i=0; i < inputFields.length; i++) {
if (!inputFields[i].validity.valid) {
inputFields[i].focus(); // set cursor to first invalid input field
return false;
}
}
}
}, false);
Within each() function I found all DOM element of text input in the old version of PC Safari, I think this code useful for newer versions on MAC using inputobj['prpertyname'] object to get all properties and values:
$('form').find("[required]").each(function(index, inputobj) {
if (inputobj['required'] == true) { // check all required fields within the form
currentValue = $(this).val();
if (currentValue.length == 0) {
// $.each((inputobj), function(input, obj) { alert(input + ' - ' + obj); }); // uncomment this row to alert names and values of DOM object
var currentName = inputobj['placeholder']; // use for alerts
return false // here is an empty input
}
}
});
function customValidate(){
var flag=true;
var fields = $('#frm-add').find('[required]'); //get required field by form_ID
for (var i=0; i< fields.length;i++){
debugger
if ($(fields[i]).val()==''){
flag = false;
$(fields[i]).focus();
}
}
return flag;
}
if (customValidate()){
// do yor work
}

Jquery replaceWith:replace one php file with another php file based on screen resolution

I need to be able to replace a php file with another php file based on screen resolution. This is what I have so far:
<script type="text/javascript">
function adjustStyle(width) {
width = parseInt(width);
if (width = 1920) {
$('book.php').replaceWith('book2.php');
}
}
$(function() {
adjustStyle($(this).width());
$(window).resize(function() {
adjustStyle($(this).width());
});
});
</script>
which obviously isn't working-- any ideas? Thank you in advance for any help received.
UPDATE
Is this at all close (to replace the book.php line)?
{ $("a[href*='book.php']").replaceWith('href', 'book2.php'); };
Second Update to reflect input gathered here
function adjustStyle(width) {
width = parseInt(width);
if (width == 1920) {
$('#bookinfo').replaceWith(['book2.php']);
$.ajax({
url: "book2.php",
}).success(function ( data ) {
$('#bookinfo').replaceWith(data);
});
$(function() {
adjustStyle($(this).width());
$(window).resize(function() {
adjustStyle($(this).width());
});
});
}
}
I have not seen the use of replaceWith in the context you put it in. Interpreting that you want to exchange the content, you may want to do so my using the load() function of jQuery.
if(width == 1920){
$("#myDiv").load("book1.php");
} else {
$("#myDiv").load("book2.php");
}
Clicking on the button replaces the content of the div to book2.php.
The first problem is I don't think that you are using the correct selectors. If you have the following container:
<div id="bookContainer">Contents of book1.php</div>
The code to replace the contents of that container should be
$('#bookContainer').replaceWith([contents of book2.php]);
In order to get [contents of book2.php] you will need to pull it in by ajax using the following code I have also included the line above so that the data from book2.php will be placed into the container:
$.ajax({
url: "http://yoururl.com/book2.php",
}).success(function ( data ) {
$('#bookContainer').replaceWith(data);
});.
I haven't tested this so there might be an issue but this is the concept you need to accomplish this.
First off... using a conditional with a single = (equal sign) will cause the condition to always be true while setting the value of variable your checking to the value your checking against.
Your condition should look like the following...
if (width == 1920) { // do something }
Second, please refer to the jQuery documentation for how to replace the entire tag with a jquery object using replaceWith()... http://api.jquery.com/replaceWith/
I would use a shorthand POST with http://api.jquery.com/jQuery.post/ since you don't have the object loaded yet...
In short, my code would look like the following using $.post instead of $.ajax assuming I had a tag with the id of "book" that originally has the contents of book.php and I wanted to replace it with the contents of book2.php...
HTML
<div id="book">*Contents of book.php*</div>
jQuery
function onResize(width) {
if (parseInt(width) >= 1920) {
$.post('book2.php',function(html){
$('#book').html(html).width(width);
});
}
else {
$.post('book.php',function(html){
$('#book').html(html).width(width);
});
}
}
Hope this helps.

adding arrow navigation to Jquery AJAX + PHP search engine

I've made a search engine for my database table where the search query gets sent by Jquery AJAX to a file called search.php. Search.php then sends the result back to the Javascript file where the results are processed and added to index.php.
Everything works perfectly except when I try to add arrow key navigation. For example, I want the first item in the search results page to be selected (by appending the class, red to it and using focus()) when I press the down arrow key, the second result to be selected when I press it again, etc..
Nothing gets selected when I press either the up or down arrow key. I'm testing this in Google Chrome.
index.php:
<link rel="stylesheet" type="text/css" href="search.css">
Start searching: <input type="text" id="search" autocomplete="off">
<div id="search_results">
</div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="search.js"></script>
javascript file:
$(document).ready(function(){
search_x = $('#search').offset().left;
search_y = $('#search').offset().top;
search_height = $('#search').height();
$('#search_results').css({
'left': search_x,
'top': (search_y + search_height + 5)
});
//arrow key navigation
start = -1;
$(document).on('keydown',document,function(e){
if(e.keyCode == 38){
if (start == -1){
start = ($('#search_results ul li a').size() - 1);
}else{
start--;
if (start < 0){
start = ($('#search_results ul li a').size() - 1);
}
}
$('#search_results ul li a').removeClass('red').focus();
$('#search_results ul li a').eq(start).addClass('red').focus();
}
if(e.keyCode == 40){
if (start == -1){
start = 0;
}else{
start++;
if (start > ($('#search_results ul li a').size() - 1)){
start = 0;
}
}
$('#search_results ul li a').removeClass('red').focus();
$('#search_results ul li a').eq(start).addClass('red').focus();
}
});
$('#search').on(
'keyup keydown',
function(){
var search_term = $(this).val();
$.post(
'search.php',
{
search_term : search_term
},function(data){
if (data == "nothing"){
$('#search_results').fadeOut();
} else {
$('#search_results').html(data).fadeIn();
}
});
});
});
part of the search.php file that sends data to index.php:
if (!empty($search_term))
{
echo '<ul>';
while ($results_row = mysql_fetch_assoc($search)){
echo '<li><a href="#">
<p><strong>',$results_row['place'],'</strong><br>',$results_row['description'],'</p>
</a>
</li>';
}
echo '</ul>';
} else {
echo "nothing";
}
I think the problem may be the on() method.
You are attaching the method to the document object, which is fine, but then also passing document as the second argument to the method. The second argument represents a selector that each event is filtered against to see if that was the element that trigerred the event. The document element won't both receive the event and originate the event (unless there are literally no elements on the page!)
try something like:
$(document).on("keydown", "#search_results", function() {
//etc
});
So the document will still receive the event, but the handler will only be triggered if the event originated from the results container
After finding some free time to code again, I changed $(document).on('keydown',document,function(e){
//stuff
}); to $(document).on('keydown','#search',function(e){
//stuff
});
The key press event listener was applied to the text field, #search. The code seemed to work after making the change.

Categories