jQuery plugin not working for multiple selections - javascript

(function ( $ ) {
$.fn.bcatUpload = function (options) {
if ( methods[options] ) {
return methods[ options ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof options === 'object' || ! options ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + options + ' does not exist on jQuery.bcatUpload' );
}
}
$.fn.bcatUpload.files_array = [];
var methods = {
init: function (arguments) {
return this.each(function(index, el) {
element = $(this);
var settings = $.extend(true, {}, $defaults, arguments);
private_methods.prepare(element);
element.change(function(event) {
event.preventDefault();
var file_list = element[0].files;
$.each(file_list, function(index, file) {
$.fn.bcatUpload.files_array.push(file);
private_methods.display(element);
});
});
});
},
remove: function (index) {
element = $(this);
$.fn.bcatUpload.files_array.splice(index, 1);
console.log($.fn.bcatUpload.files_array);
private_methods.display(element);
},
upload: function () {
// Start the upload...
console.log('Uploading...');
console.log($.fn.bcatUpload.files_array);
return methods;
}
};
var private_methods = {
prepare: function (element) {
$html = element.wrap('<div class="bcat-upload-container"></div>').parent();
element.hide();
var btn_class= ($defaults.button.class == null) ? '' : 'class="'+$defaults.button.class+'"';
$html.append('<button type="button" '+btn_class+'>'+$defaults.button.label+'</button>');
$html.append('<div class="bcat-file-list"></div><div class="bcat-clear"></div>');
$html.find('button').click(function(event) {
element.click();
});
},
display: function (element) {
$html = element.siblings('.bcat-file-list');
var file_string = '';
$.each($.fn.bcatUpload.files_array, function(index, file) {
file_name = private_methods.formatFileName(file);
file_string += '<blockquote><span class="filename">'+file_name+'</span>';
file_string += '<a class="close" href="javascript:$('+element.attr('id')+').bcatUpload(\'remove\', '+index+');" data-index="'+index+'">';
file_string += '×</a></blockquote>';
});
$html.html(file_string);
// Register the Click Event Handler.
// $html.find('blockquote a.close').click(function(event) {
// methods.remove($(this).attr('data-index'));
// });
},
formatFileName: function (file) {
var filename = private_methods.getFileName(file.name);
var ext = private_methods.getExtension(file.name);
if (filename.length > 20) {
filename = filename.substring(0, 20) + '..';
}
return filename + '.' + ext;
},
getExtension: function (filename) {
var file_name_array = filename.split('.');
return file_name_array[file_name_array.length - 1];
},
getFileName: function (filename) {
var file_name_array = filename.split('.');
var ext = private_methods.getExtension(filename);
return filename.substring(0, filename.length - parseInt(ext.length) - 1);
},
getHumanSize: function (bytes, si) {
var thresh = si ? 1000 : 1024;
if(Math.abs(bytes) < thresh) {
return bytes + ' B';
}
var units = si
? ['KB','MB','GB','TB','PB','EB','ZB','YB']
: ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
var u = -1;
do {
bytes /= thresh;
++u;
} while(Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1)+' '+units[u];
}
}
var $defaults = {
id : $(this).attr('id'),
url : '',
data : {},
type : 'image',
size : {
min : null, // 1024 => 1KB.
max : null, // 2097152 => 2MB.
total : null, // 4194304 => 4MB.
},
dimention : {
min : [null, null],
max : [null, null]
},
allowed : {
ext : [],
mimes : {
image : [
'image/jpeg', // JPG/JPEG image.
'image/gif', // GIF image.
'image/png', // PNG image.
'image/bmp' // BMP Image
],
file: [
'application/pdf', // PDF file.
'application/msword', // DOC file.
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' // DOCX file.
]
}
},
button : {
class : null,
label : 'Select File',
icon : null
},
limit : 0
}
}( jQuery ));
$(":file").bcatUpload({
size: {
min: 2048,
max: 50000000
}
});
div.bcat-upload-container {
display:block;
clear:both;
}
div.bcat-upload-container button, #upload {
background: darkred;
padding:10px 15px;
border-width: 0px;
color:#F2F2F2;
font-weight:bold;
border-radius: 3px;
}
div.bcat-upload-container .bcat-clear {clear: both;}
div.bcat-upload-container div.bcat-file-list {
display: block;
clear: both;
}
div.bcat-upload-container div.bcat-file-list blockquote {
padding: 10px;
margin: 10px;
display: block;
border-left: 2px solid #ccc;
border-bottom: 1px solid #ccc;
}
div.bcat-upload-container div.bcat-file-list blockquote .filename {
font-size: 12px;
font-family: 'Courier New';
}
div.bcat-upload-container div.bcat-file-list blockquote a {
text-decoration: none;
float: right;
}
#upload {background: darkgreen;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<form action="" method="POST">
<input type="file" id="docs1" multiple /><br />
<input type="file" id="docs2" multiple /><br />
<input type="button" value="Upload" id="upload" onclick="$(':file').bcatUpload('upload');" />
</form>
Above is the plugin for file upload. The above code works when there is only one file element selected. But if I select multiple then it stops working correctly. It only works for the last one that I instantiate.
I can't figure out what went wrong.
Note: The file upload process through ajax is not included here... I just wan't to have the selected files array set up for each of the file elements I have in the html. Then I can commence the upload method to execute the ajax file upload.

Related

laravel undefined offset 0 laravel 8 resources

hello i have this error : Undefined offset: 0 (View: /home/me/www/me/resources/views/contact.blade.php) i was try to create crud in admin panel for contact page. when i try to go in for edit this page, i have this error
Undefined offset: 0 (View: /home/.../www/.../resources/views/contact.blade.php) and if i remplace all data by {{ dd($data) }} i have this
Address
<script> Sfdump = window.Sfdump || (function (doc) { var refStyle = doc.createElement('style'), rxEsc = /([.*+?^${}()|\[\]\/\\])/g, idRx = /\bsf-dump-\d+-ref[012]\w+\b/, keyHint = 0 <= navigator.platform.toUpperCase().indexOf('MAC') ? 'Cmd' : 'Ctrl', addEventListener = function (e, n, cb) { e.addEventListener(n, cb, false); }; (doc.documentElement.firstElementChild || doc.documentElement.children[0]).appendChild(refStyle); if (!doc.addEventListener) { addEventListener = function (element, eventName, callback) { element.attachEvent('on' + eventName, function (e) { e.preventDefault = function () {e.returnValue = false;}; e.target = e.srcElement; callback(e); }); }; } function toggle(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className, arrow, newClass; if (/\bsf-dump-compact\b/.test(oldClass)) { arrow = '▼'; newClass = 'sf-dump-expanded'; } else if (/\bsf-dump-expanded\b/.test(oldClass)) { arrow = '▶'; newClass = 'sf-dump-compact'; } else { return false; } if (doc.createEvent && s.dispatchEvent) { var event = doc.createEvent('Event'); event.initEvent('sf-dump-expanded' === newClass ? 'sfbeforedumpexpand' : 'sfbeforedumpcollapse', true, false); s.dispatchEvent(event); } a.lastChild.innerHTML = arrow; s.className = s.className.replace(/\bsf-dump-(compact|expanded)\b/, newClass); if (recursive) { try { a = s.querySelectorAll('.'+oldClass); for (s = 0; s < a.length; ++s) { if (-1 == a[s].className.indexOf(newClass)) { a[s].className = newClass; a[s].previousSibling.lastChild.innerHTML = arrow; } } } catch (e) { } } return true; }; function collapse(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-expanded\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function expand(a, recursive) { var s = a.nextSibling || {}, oldClass = s.className; if (/\bsf-dump-compact\b/.test(oldClass)) { toggle(a, recursive); return true; } return false; }; function collapseAll(root) { var a = root.querySelector('a.sf-dump-toggle'); if (a) { collapse(a, true); expand(a); return true; } return false; } function reveal(node) { var previous, parents = []; while ((node = node.parentNode || {}) && (previous = node.previousSibling) && 'A' === previous.tagName) { parents.push(previous); } if (0 !== parents.length) { parents.forEach(function (parent) { expand(parent); }); return true; } return false; } function highlight(root, activeNode, nodes) { resetHighlightedNodes(root); Array.from(nodes||[]).forEach(function (node) { if (!/\bsf-dump-highlight\b/.test(node.className)) { node.className = node.className + ' sf-dump-highlight'; } }); if (!/\bsf-dump-highlight-active\b/.test(activeNode.className)) { activeNode.className = activeNode.className + ' sf-dump-highlight-active'; } } function resetHighlightedNodes(root) { Array.from(root.querySelectorAll('.sf-dump-str, .sf-dump-key, .sf-dump-public, .sf-dump-protected, .sf-dump-private')).forEach(function (strNode) { strNode.className = strNode.className.replace(/\bsf-dump-highlight\b/, ''); strNode.className = strNode.className.replace(/\bsf-dump-highlight-active\b/, ''); }); } return function (root, x) { root = doc.getElementById(root); var indentRx = new RegExp('^('+(root.getAttribute('data-indent-pad') || ' ').replace(rxEsc, '\\$1')+')+', 'm'), options = {
options.maxDepth)) { toggle(a); } } else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) { a = a.substr(1); elt.className += ' '+a; if (/[\[{]$/.test(elt.previousSibling.nodeValue)) { a = a != elt.nextSibling.id && doc.getElementById(a); try { s = a.nextSibling; elt.appendChild(a); s.parentNode.insertBefore(a, s); if (/^[##]/.test(elt.innerHTML)) { elt.innerHTML += ' ▶'; } else { elt.innerHTML = '▶'; elt.className = 'sf-dump-ref'; } elt.className += ' sf-dump-toggle'; } catch (e) { if ('&' == elt.innerHTML.charAt(0)) { elt.innerHTML = '…'; elt.className = 'sf-dump-ref'; } } } } } if (doc.evaluate && Array.from && root.children.length > 1) { root.setAttribute('tabindex', 0); SearchState = function () { this.nodes = []; this.idx = 0; }; SearchState.prototype = { next: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx < (this.nodes.length - 1) ? this.idx + 1 : 0; return this.current(); }, previous: function () { if (this.isEmpty()) { return this.current(); } this.idx = this.idx > 0 ? this.idx - 1 : (this.nodes.length - 1); return this.current(); }, isEmpty: function () { return 0 === this.count(); }, current: function () { if (this.isEmpty()) { return null; } return this.nodes[this.idx]; }, reset: function () { this.nodes = []; this.idx = 0; }, count: function () { return this.nodes.length; }, }; function showCurrent(state) { var currentNode = state.current(), currentRect, searchRect; if (currentNode) { reveal(currentNode); highlight(root, currentNode, state.nodes); if ('scrollIntoView' in currentNode) { currentNode.scrollIntoView(true); currentRect = currentNode.getBoundingClientRect(); searchRect = search.getBoundingClientRect(); if (currentRect.top < (searchRect.top + searchRect.height)) { window.scrollBy(0, -(searchRect.top + searchRect.height + 5)); } } } counter.textContent = (state.isEmpty() ? 0 : state.idx + 1) + ' of ' + state.count(); } var search = doc.createElement('div'); search.className = 'sf-dump-search-wrapper sf-dump-search-hidden'; search.innerHTML = '
0 of 0<\/span> '+h+' ◀'+ ''+elt.innerHTML+' ▶'; } } } catch (e) { } }; })(document);
Illuminate\Database\Eloquent\Collection {#1218
#items: []
}
contact blade
<?php
/**
* Created by PhpStorm.
* User: abhi
* Date: 10/20/2020
* Time: 5:54 PM
*/?>
#extends('layouts.app')
<style>
body {
font-family: "Lato", sans-serif;
}
.sidenav {
height: 100%;
width: 160px;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: #111;
overflow-x: hidden;
padding-top: 20px;
}
.sidenav a {
padding: 6px 8px 6px 16px;
text-decoration: none;
font-size: 25px;
color: #818181;
display: block;
}
.sidenav a:hover {
color: #f1f1f1;
}
.main {
margin-left: 160px; /* Same as the width of the sidenav */
font-size: 28px; /* Increased text to enable scrolling */
padding: 0px 10px;
}
#media screen and (max-height: 450px) {
.sidenav {padding-top: 15px;}
.sidenav a {font-size: 18px;}
}
</style>
#section('content')
<!-- CSS only -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
{{--<div class="sidenav">--}}
{{--Post--}}
{{--Categories--}}
{{--Footer--}}
{{--Society--}}
{{--</div>--}}
<section style="padding-top:60px;">
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3">
<div class="card">
<div class="card-header">
Update Contact Details...
</div>
<div class="card-body">
#if(Session::has('status'))
<div class="alert alert-success" role="alert">
{{Session::get('status')}}
</div>
#endif
<form id="insert" method="POST" action="{{url('updatecontact')}}"
enctype="multipart/form-data">
#csrf
<div class="form-group">
<label for="h1">Address</label>
<input type="text" value="{{$data[0]->address}}" name="address" class="form-control"/>
<label for="h2">Contact(1)</label>
<input type="tel" value="{{$data[0]->contact1}}" name="contact1" class="form-control"/>
<label for="h2">Contact(2)</label>
<input type="tel" value="{{$data[0]->contact2}}" name="contact2" class="form-control"/>
<label for="h2">Fax</label>
<input type="tel" value="{{$data[0]->fax}}" name="fax" class="form-control"/>
<label for="h2">E-mail</label>
<input type="email" value="{{$data[0]->email}}" name="email" class="form-control"/>
<br>
<input type="hidden" value="{{$data[0]->id}}" name="rowid">
</div>
<button type="submit" class="btn btn-primary">Update Details</button>
</form>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- JS, Popper.js, and jQuery -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.1/dist/umd/popper.min.js"
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"
integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV"
crossorigin="anonymous"></script>
<script>
function previewFile1(input) {
var file1 = $(input).get(0).files[0];
if (file1) {
var reader = new FileReader();
reader.onload = function () {
$('#previewImg1').attr("src", reader.result);
}
reader.readAsDataURL(file1);
}
}
</script>
#endsection
controller
<?php
namespace App\Http\Controllers;
use App\Mail\ContactMail;
use App\Models\Contact;
use App\Models\ContactDetails;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
class ContactController extends Controller
{
function index(){
$this->middleware('auth');
$data['data'] = Contact::all();
return view('contact', $data);
}
function updateContact(Request $request){
$this->middleware('auth');
$data['address'] = $request->address;
$data['contact1'] = $request->contact1;
$data['contact2'] = $request->contact2;
$data['fax'] = $request->fax;
$data['email'] = $request->email;
$affected = DB::table('contacts')
->where('id', '=', $request->rowid)
->update($data);
return back()->with('status', 'Contact Details are Updated');
}
function sendContact(Request $request){
$contact = new ContactDetails();
$contact->name = $request->name;
$contact->email = $request->email;
$contact->phone = $request->phone;
$contact->msg = $request->message;
$contact->save();
$dataObject = new \stdClass();
$dataObject->name = $request->name;
$dataObject->email = $request->email;
$dataObject->phone = $request->phone;
$dataObject->msg = $request->message;
Mail::to('mokoch.web#gmail.com')->send(new ContactMail($dataObject));
return back()->with('status', 'Contact Details are Updated');
}
}
i try to create update for contact and i was hosted this but i have this i dont know how resolve... because crud for footer and other work whithout problem. it's in laravel 8
Honestly I would refactor the following
$data['data'] = Contact::all();
to
$contacts = Contact::all();
Remember that Contact::all(); is going to return an array of collections so you would need to loop through $contacts on your index view.
if you are trying to update a contact you need to get the specific contact first for example:
$contact = Contact::find($id);
Then in your blade you can simply use $contact->email instead of $data[0]->email
So in your situation you need to create a show method that accepts an id as a parameter then you can find the record you want to update and use the example above.
A good resource if you are new CodersTape

Rater.js - Half stars instead of full stars for progress

Hy there! I plan to use Rater.js in my project and so far I am happy with the library. There is only one issue I can't resolve alone. Pls. take a look at
https://jsfiddle.net/herbert_hinterberger/r1cgnpt3/.
At the very bottom of the script, I defined step_size: 1.
(".rating").rate();
//or for example
var options = {
max_value: 5,
step_size: 1,
}
Now I would expect that when I hover over the stars, only full stars are selected. But still, half stars are selected too. Any Idea what I a doing wrong?
In your example code, you are calling $(".rating").rate(); without options (line number 499).
After commenting it, you will end-up with something like below
/*
* A highly customizable rating widget that supports images, utf8 glyphs and other html elements!
* https://github.com/auxiliary/rater
*/
; (function ($, window) {
$.fn.textWidth = function () {
var html_calc = $('<span>' + $(this).html() + '</span>');
html_calc.css('font-size', $(this).css('font-size')).hide();
html_calc.prependTo('body');
var width = html_calc.width();
html_calc.remove();
if (width == 0) {
var total = 0;
$(this).eq(0).children().each(function () {
total += $(this).textWidth();
});
return total;
}
return width;
};
$.fn.textHeight = function () {
var html_calc = $('<span>' + $(this).html() + '</span>');
html_calc.css('font-size', $(this).css('font-size')).hide();
html_calc.prependTo('body');
var height = html_calc.height();
html_calc.remove();
return height;
};
/*
* IE8 doesn't support isArray!
*/
Array.isArray = function (obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
};
/*
* Utf-32 isn't supported by default, so we have to use Utf-8 surrogates
*/
String.prototype.getCodePointLength = function () {
return this.length - this.split(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g).length + 1;
};
String.fromCodePoint = function () {
var chars = Array.prototype.slice.call(arguments);
for (var i = chars.length; i-- > 0;) {
var n = chars[i] - 0x10000;
if (n >= 0)
chars.splice(i, 1, 0xD800 + (n >> 10), 0xDC00 + (n & 0x3FF));
}
return String.fromCharCode.apply(null, chars);
};
/*
* Starting the plugin itself
*/
$.fn.rate = function (options) {
if (options === undefined || typeof options === 'object') {
return this.each(function () {
if (!$.data(this, "rate")) {
$.data(this, "rate", new Rate(this, options));
}
});
}
else if (typeof options === 'string') {
var args = arguments;
var returns;
this.each(function () {
var instance = $.data(this, "rate");
if (instance instanceof Rate && typeof instance[options] === 'function') {
returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1));
}
if (options === 'destroy') {
// Unbind all events and empty the plugin data from instance
$(instance.element).off();
$.data(this, 'rate', null);
}
});
return returns !== undefined ? returns : this;
}
};
function Rate(element, options) {
this.element = element;
this.settings = $.extend({}, $.fn.rate.settings, options);
this.set_faces = {}; // value, symbol pairs
this.build();
}
Rate.prototype.build = function () {
this.layers = {};
this.value = 0;
this.raise_select_layer = false;
if (this.settings.initial_value) {
this.value = this.settings.initial_value;
}
if ($(this.element).attr("data-rate-value")) {
this.value = $(this.element).attr("data-rate-value");
}
/*
* Calculate the selected width based on the initial value
*/
var selected_width = this.value / this.settings.max_value * 100;
/*
* Let's support single strings as symbols as well as objects
*/
if (typeof this.settings.symbols[this.settings.selected_symbol_type] === 'string') {
var symbol = this.settings.symbols[this.settings.selected_symbol_type];
this.settings.symbols[this.settings.selected_symbol_type] = {};
this.settings.symbols[this.settings.selected_symbol_type]['base'] = symbol;
this.settings.symbols[this.settings.selected_symbol_type]['selected'] = symbol;
this.settings.symbols[this.settings.selected_symbol_type]['hover'] = symbol;
}
/*
* Making the three main layers (base, select, hover)
*/
var base_layer = this.addLayer("base-layer", 100, this.settings.symbols[
this.settings.selected_symbol_type]["base"], true);
var select_layer = this.addLayer("select-layer", selected_width,
this.settings.symbols[this.settings.selected_symbol_type]["selected"], true);
var hover_layer = this.addLayer("hover-layer", 0, this.settings.symbols[
this.settings.selected_symbol_type]["hover"], false);
/* var face_layer = this.addLayer("face-layer", 1, this.settings
.symbols[this.settings.face_layer_symbol_type][0], true); */
this.layers["base_layer"] = base_layer;
this.layers["select_layer"] = select_layer;
this.layers["hover_layer"] = hover_layer;
/*
* Bind the container to some events
*/
$(this.element).on("mousemove", $.proxy(this.hover, this));
$(this.element).on("click", $.proxy(this.select, this));
$(this.element).on("mouseleave", $.proxy(this.mouseout, this));
/*
* Set the main element as unselectable
*/
$(this.element).css({
"-webkit-touch-callout": "none",
"-webkit-user-select": "none",
"-khtml-user-select": "none",
"-moz-user-select": "none",
"-ms-user-select": "none",
"user-select": "none",
});
/*
* Update custom input field if provided
*/
if (this.settings.hasOwnProperty("update_input_field_name")) {
this.settings.update_input_field_name.val(this.value);
}
}
/*
* Function to add a layer
*/
Rate.prototype.addLayer = function (layer_name, visible_width, symbol, visible) {
var layer_body = "<div>";
for (var i = 0; i < this.settings.max_value; i++) {
if (Array.isArray(symbol)) {
if (this.settings.convert_to_utf8) {
symbol[i] = String.fromCodePoint(symbol[i]);
}
layer_body += "<span>" + (symbol[i]) + "</span>";
}
else {
if (this.settings.convert_to_utf8) {
symbol = String.fromCodePoint(symbol);
}
layer_body += "<span>" + symbol + "</span>";
}
}
layer_body += "</div>";
var layer = $(layer_body).addClass("rate-" + layer_name).appendTo(this.element);
$(layer).css({
width: visible_width + "%",
height: $(layer).children().eq(0).textHeight(),
overflow: 'hidden',
position: 'absolute',
top: 0,
display: visible ? 'block' : 'none',
'white-space': 'nowrap'
});
$(this.element).css({
width: $(layer).textWidth() + "px",
height: $(layer).height(),
position: 'relative',
cursor: this.settings.cursor,
});
return layer;
}
Rate.prototype.updateServer = function () {
if (this.settings.url != undefined) {
$.ajax({
url: this.settings.url,
type: this.settings.ajax_method,
data: $.extend({}, { value: this.getValue() }, this.settings.additional_data),
success: $.proxy(function (data) {
$(this.element).trigger("updateSuccess", [data]);
}, this),
error: $.proxy(function (jxhr, msg, err) {
$(this.element).trigger("updateError", [jxhr, msg, err]);
}, this)
});
}
}
Rate.prototype.getValue = function () {
return this.value;
}
Rate.prototype.hover = function (ev) {
var pad = parseInt($(this.element).css("padding-left").replace("px", ""));
var x = ev.pageX - $(this.element).offset().left - pad;
var val = this.toValue(x, true);
if (val != this.value) {
this.raise_select_layer = false;
}
if (!this.raise_select_layer && !this.settings.readonly) {
var visible_width = this.toWidth(val);
this.layers.select_layer.css({ display: 'none' });
if (!this.settings.only_select_one_symbol) {
this.layers.hover_layer.css({
width: visible_width + "%",
display: 'block'
});
}
else {
var index_value = Math.floor(val);
this.layers.hover_layer.css({
width: "100%",
display: 'block'
});
this.layers.hover_layer.children("span").css({
visibility: 'hidden',
});
this.layers.hover_layer.children("span").eq(index_value != 0 ? index_value - 1 : 0).css({
visibility: 'visible',
});
}
}
}
/*
* Event for when a rating has been selected (clicked)
*/
Rate.prototype.select = function (ev) {
if (!this.settings.readonly) {
var old_value = this.getValue();
var pad = parseInt($(this.element).css("padding-left").replace("px", ""));
var x = ev.pageX - $(this.element).offset().left - pad;
var selected_width = this.toWidth(this.toValue(x, true));
this.setValue(this.toValue(selected_width));
this.raise_select_layer = true;
}
}
Rate.prototype.mouseout = function () {
this.layers.hover_layer.css({ display: 'none' });
this.layers.select_layer.css({ display: 'block' });
}
/*
* Takes a width (px) and returns the value it resembles
*/
Rate.prototype.toWidth = function (val) {
return val / this.settings.max_value * 100;
}
/*
* Takes a value and calculates the width of the selected/hovered layer
*/
Rate.prototype.toValue = function (width, in_pixels) {
var val;
if (in_pixels) {
val = width / this.layers.base_layer.textWidth() * this.settings.max_value;
}
else {
val = width / 100 * this.settings.max_value;
}
// Make sure the division doesn't cause some small numbers added by
// comparing to a small arbitrary number.
var temp = val / this.settings.step_size;
if (temp - Math.floor(temp) < 0.00005) {
val = Math.round(val / this.settings.step_size) * this.settings.step_size;
}
val = (Math.ceil(val / this.settings.step_size)) * this.settings.step_size;
val = val > this.settings.max_value ? this.settings.max_value : val;
return val;
}
Rate.prototype.getElement = function (layer_name, index) {
return $(this.element).find(".rate-" + layer_name + " span").eq(index - 1);
}
Rate.prototype.getLayers = function () {
return this.layers;
}
Rate.prototype.setFace = function (value, face) {
this.set_faces[value] = face;
}
Rate.prototype.setAdditionalData = function (data) {
this.settings.additional_data = data;
}
Rate.prototype.getAdditionalData = function () {
return this.settings.additional_data;
}
Rate.prototype.removeFace = function (value) {
delete this.set_faces[value];
}
Rate.prototype.setValue = function (value) {
if (!this.settings.readonly) {
if (value < 0) {
value = 0;
}
else if (value > this.settings.max_value) {
value = this.settings.max_value;
}
var old_value = this.getValue();
this.value = value;
/*
* About to change event, should support prevention later
*/
var change_event = $(this.element).trigger("change", {
"from": old_value,
"to": this.value
});
/*
* Set/Reset faces
*/
$(this.element).find(".rate-face").remove();
$(this.element).find("span").css({
visibility: 'visible'
});
var index_value = Math.ceil(this.value);
if (this.set_faces.hasOwnProperty(index_value)) {
var face = "<div>" + this.set_faces[index_value] + "</div>";
var base_layer_element = this.getElement('base-layer', index_value);
var select_layer_element = this.getElement('select-layer', index_value);
var hover_layer_element = this.getElement('hover-layer', index_value);
var left_pos = base_layer_element.textWidth() * (index_value - 1)
+ (base_layer_element.textWidth() - $(face).textWidth()) / 2;
$(face).appendTo(this.element).css({
display: 'inline-block',
position: 'absolute',
left: left_pos,
}).addClass("rate-face");
base_layer_element.css({
visibility: 'hidden'
});
select_layer_element.css({
visibility: 'hidden'
});
hover_layer_element.css({
visibility: 'hidden'
});
}
/*
* Set styles based on width and value
*/
if (!this.settings.only_select_one_symbol) {
var width = this.toWidth(this.value);
this.layers.select_layer.css({
display: 'block',
width: width + "%",
height: this.layers.base_layer.css("height")
});
this.layers.hover_layer.css({
display: 'none',
height: this.layers.base_layer.css("height")
});
}
else {
var width = this.toWidth(this.settings.max_value);
this.layers.select_layer.css({
display: 'block',
width: width + "%",
height: this.layers.base_layer.css("height")
});
this.layers.hover_layer.css({
display: 'none',
height: this.layers.base_layer.css("height")
});
this.layers.select_layer.children("span").css({
visibility: 'hidden',
});
this.layers.select_layer.children("span").eq(index_value != 0 ? index_value - 1 : 0).css({
visibility: 'visible',
});
}
// Update the data-rate-value attribute
$(this.element).attr("data-rate-value", this.value);
if (this.settings.change_once) {
this.settings.readonly = true;
}
this.updateServer();
/*
* After change event
*/
var change_event = $(this.element).trigger("afterChange", {
"from": old_value,
"to": this.value
});
/*
* Update custom input field if provided
*/
if (this.settings.hasOwnProperty("update_input_field_name")) {
this.settings.update_input_field_name.val(this.value);
}
}
}
Rate.prototype.increment = function () {
this.setValue(this.getValue() + this.settings.step_size);
}
Rate.prototype.decrement = function () {
this.setValue(this.getValue() - this.settings.step_size);
}
$.fn.rate.settings = {
max_value: 5,
step_size: 0.5,
initial_value: 0,
symbols: {
utf8_star: {
base: '\u2606',
hover: '\u2605',
selected: '\u2605',
},
utf8_hexagon: {
base: '\u2B21',
hover: '\u2B22',
selected: '\u2B22',
},
hearts: '♥',
fontawesome_beer: '<i class="fa fa-beer"></i>',
fontawesome_star: {
base: '<i class="fa fa-star-o"></i>',
hover: '<i class="fa fa-star"></i>',
selected: '<i class="fa fa-star"></i>',
},
utf8_emoticons: {
base: [0x1F625, 0x1F613, 0x1F612, 0x1F604],
hover: [0x1F625, 0x1F613, 0x1F612, 0x1F604],
selected: [0x1F625, 0x1F613, 0x1F612, 0x1F604],
},
},
selected_symbol_type: 'utf8_star', // Must be a key from symbols
convert_to_utf8: false,
cursor: 'default',
readonly: false,
change_once: false, // Determines if the rating can only be set once
only_select_one_symbol: false, // If set to true, only selects the hovered/selected symbol and nothing prior to it
ajax_method: 'POST',
additional_data: {}, // Additional data to send to the server
//update_input_field_name = some input field set by the user
};
}(jQuery, window));
//$(".rating").rate();
//or for example
var options = {
max_value: 5,
step_size: 1,
}
$(".rating").rate(options);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="rating" data-rate-value=6></div>
You are specifying the options at an earlier stage in your code.
See here:
$.fn.rate.settings = {
max_value: 5,
step_size: 0.5,
I tested in your fiddle and it works when updated to 1 step_size.

Jquery Plugin. Options for each instances

I've created a jquery plugin that is called several times inside the same page. Each time I call the plugin I pass differents parameters and a callback function that returns the ID of the element, that it's passed as parameter but I always receive the ID of the last element that has been applied the plugin.
I always thought that everytime I call a plugin a new instance is generated.
This is my plugin code:
(function ($) {
$.audioRecorder = {
constants: {
},
options: {
domain: "http://example.com",
storageUrl: "/services/uploader/uploadtoazure",
storageUrlIOSDevice: "/services/uploader/uploadaudiofromiosdevice",
storageAudioContainer: null,
storageAudioPath: null,
storageMimeType: "audio/mpeg",
storageExtension: "mp3",
container: null,
handlerInterval: null,
callbackAudioSaved: null,
callbackPlay: null,
callbackStop: null,
id: null
},
methods: {
init: function (options) {
$.extend(true, $.audioRecorder.options, options);
window.microm = new Microm();
$.audioRecorder.options.container = $(this);
$.audioRecorder.methods.build();
$.audioRecorder.methods.bind();
},
build: function () {
var template = $.audioRecorder.templates.recorder.replace(/##domain##/g, $.audioRecorder.options.domain.replace('https','http'));
$.audioRecorder.options.container.html(template);
$.audioRecorder.methods.showRecordButton();
if ($.audioRecorder.methods.isIOSDevice()) {
$.audioRecorder.options.container.find(".audio-recorder-timer").hide();
}
},
bind: function () {
$.audioRecorder.options.container.find(".audio-recorder-record").click($.audioRecorder.methods.record);
$.audioRecorder.options.container.find(".audio-recorder-stop").click($.audioRecorder.methods.stop);
$.audioRecorder.options.container.find(".audio-recorder-uploader").change($.audioRecorder.methods.saveAudioFromFileUpload);
},
record: function () {
if ($.audioRecorder.methods.isIOSDevice()) {
$.audioRecorder.options.container.find(".audio-recorder-uploader").click();
}
else {
microm.record().then(function () {
$.audioRecorder.methods.initTimer();
$.audioRecorder.methods.showStopButton();
console.log('Recording...');
}).catch(function (error) {
console.log('error recording', error);
});
}
},
stop: function () {
$.audioRecorder.methods.stopTimer();
$.audioRecorder.methods.showLoading();
microm.stop().then(function (mp3) {
$.audioRecorder.methods.saveAudio(mp3);
console.log('Stop record');
});
},
saveAudio: function (mp3) {
var fd = new FormData();
fd.append('data', mp3.blob);
fd.append('container', $.audioRecorder.options.storageAudioContainer);
fd.append('path', $.audioRecorder.options.storageAudioPath);
fd.append('extension', $.audioRecorder.options.storageExtension);
fd.append('mimeType', $.audioRecorder.options.storageMimeType);
$.ajax({
url: $.audioRecorder.options.domain + $.audioRecorder.options.storageUrl,
type: 'post',
data: fd,
processData: false,
contentType: false,
success: function (url) {
$.audioRecorder.methods.audioSaved(url);
},
error: function () {
$.audioRecorder.methods.showRecordButton();
}
});
},
saveAudioFromFileUpload: function () {
if ($.audioRecorder.options.container.find(".audio-recorder-uploader")[0].files == null || $.audioRecorder.options.container.find(".audio-recorder-uploader")[0].files.length == 0) {
return;
}
$.audioRecorder.methods.showLoading();
var file = $.audioRecorder.options.container.find(".audio-recorder-uploader")[0].files[0];
var fd = new FormData();
fd.append('data', file);
fd.append('container', $.audioRecorder.options.storageAudioContainer);
fd.append('path', $.audioRecorder.options.storageAudioPath);
fd.append('mimeType', $.audioRecorder.options.storageMimeType);
$.ajax({
url: $.audioRecorder.options.domain + $.audioRecorder.options.storageUrlIOSDevice,
type: 'post',
data: fd,
processData: false,
contentType: false,
success: function (data) {
$.audioRecorder.methods.audioSaved(data.url, data.duration);
},
error: function () {
$.audioRecorder.methods.showRecordButton();
}
});
},
audioSaved: function (url, duration) {
$.audioRecorder.methods.showRecordButton();
var timer = $.audioRecorder.methods.getTimer();
$.audioRecorder.methods.resetTimer();
if (duration != null) {
var seconds = duration % 60;
var minutes = Math.floor(duration / 60);
timer = minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
}
var template = $.audioRecorder.templates.player;
template = template.replace(/##link##/g, url);
template = template.replace(/##length##/g, timer);
template = template.replace(/##domain##/g, $.audioRecorder.options.domain.replace('https','http'));
if ($.audioRecorder.options.callbackPlay != null) {
template = template.replace(/##callbackPlay##/g, $.audioRecorder.options.callbackPlay.name + "(event)");
}
else {
template = template.replace(/##callbackPlay##/g, "");
}
if ($.audioRecorder.options.callbackStop != null) {
template = template.replace(/##callbackStop##/g, $.audioRecorder.options.callbackStop.name + "(event)");
}
else {
template = template.replace(/##callbackStop##/g, "");
}
if ($.audioRecorder.options.callbackAudioSaved != null) {
$.audioRecorder.options.callbackAudioSaved(url, template, $.audioRecorder.options.container);
}
else {
$.audioRecorder.options.container.append(template);
}
},
initTimer: function () {
$.audioRecorder.methods.resetTimer();
$.audioRecorder.options.handlerInterval = setInterval($.audioRecorder.methods.addSecondToTimer, 1000);
},
resetTimer: function () {
$.audioRecorder.options.container.find(".audio-recorder-timer").text("0:00");
},
addSecondToTimer: function () {
var timerText = $.audioRecorder.options.container.find(".audio-recorder-timer").text().split(":");
var minutes = parseInt(timerText[0]);
var seconds = parseInt(timerText[1]);
seconds++;
if (seconds >= 60) {
minutes++;
seconds = 0;
}
timerText = minutes + ":" + (seconds < 10 ? "0" + seconds : seconds);
$.audioRecorder.options.container.find(".audio-recorder-timer").text(timerText);
},
stopTimer: function () {
clearInterval($.audioRecorder.options.handlerInterval);
},
getTimer: function () {
return $.audioRecorder.options.container.find(".audio-recorder-timer").text();
},
getSecondsTimer: function () {
var timerText = $.audioRecorder.options.container.find(".audio-recorder-timer").text().split(":");
var minutes = parseInt(timerText[0]);
var seconds = parseInt(timerText[1]);
return minutes * 60 + seconds;
},
showRecordButton: function () {
$.audioRecorder.options.container.find(".audio-recorder-record").show();
$.audioRecorder.options.container.find(".audio-recorder-stop").hide();
$.audioRecorder.options.container.find(".audio-recorder-loading").hide();
},
showStopButton: function () {
$.audioRecorder.options.container.find(".audio-recorder-record").hide();
$.audioRecorder.options.container.find(".audio-recorder-stop").show();
$.audioRecorder.options.container.find(".audio-recorder-loading").hide();
},
showLoading: function () {
$.audioRecorder.options.container.find(".audio-recorder-record").hide();
$.audioRecorder.options.container.find(".audio-recorder-stop").hide();
$.audioRecorder.options.container.find(".audio-recorder-loading").show();
},
playerPlay: function (event) {
event.stopPropagation();
event.preventDefault();
var player = $(event.target).closest('.audio-recorder-player');
player.find('audio')[0].play();
$.audioRecorder.methods.stopPlayerTimer(player);
$.audioRecorder.methods.initPlayerTimer(player);
$.audioRecorder.methods.showPlayerStopButton(player);
},
playerStop: function (event) {
event.stopPropagation();
event.preventDefault();
var player = $(event.target).closest('.audio-recorder-player');
player.find('audio')[0].pause();
player.find('audio')[0].currentTime = 0;
$.audioRecorder.methods.stopPlayerTimer(player);
$.audioRecorder.methods.resetPlayerTimer(player);
$.audioRecorder.methods.showPlayerPlayButton(player);
},
initPlayerTimer: function (player) {
$.audioRecorder.methods.resetPlayerTimer(player);
player.prop("interval", setInterval(function () { $.audioRecorder.methods.addSecondToPlayerTimer(player); }, 1000));
},
resetPlayerTimer: function (player) {
player.find(".audio-recorder-player-current-seek").text("0:00");
player.find(".audio-recorder-player-progress-bar").width(0);
},
addSecondToPlayerTimer: function (player) {
if (player.find(".audio-recorder-player-current-seek").text() == player.find(".audio-recorder-player-total-time").text()) {
$.audioRecorder.methods.stopPlayerTimer(player);
$.audioRecorder.methods.showPlayerPlayButton(player);
return;
}
var timerText = player.find(".audio-recorder-player-current-seek").text().split(":");
var minutes = parseInt(timerText[0]);
var seconds = parseInt(timerText[1]);
seconds++;
if (seconds >= 60) {
minutes++;
seconds = 0;
}
timerText = minutes + ":" + (seconds < 10 ? "0" + seconds : seconds);
player.find(".audio-recorder-player-current-seek").text(timerText);
// Progress bar
var currentSecons = $.audioRecorder.methods.getSecondsPlayerTimer(player);
var totalSecons = $.audioRecorder.methods.getSecondsTotalPlayerTimer(player);
var progress = parseFloat(currentSecons) / parseFloat(totalSecons);
var totalWidth = player.find(".audio-recorder-player-progress-bar-parent").width();
player.find(".audio-recorder-player-progress-bar").width(progress * totalWidth);
},
stopPlayerTimer: function (player) {
clearInterval(player.prop("interval"));
},
getSecondsPlayerTimer: function (player) {
var timerText = player.find(".audio-recorder-player-current-seek").text().split(":");
var minutes = parseInt(timerText[0]);
var seconds = parseInt(timerText[1]);
return minutes * 60 + seconds;
},
getSecondsTotalPlayerTimer: function (player) {
var timerText = player.find(".audio-recorder-player-total-time").text().split(":");
var minutes = parseInt(timerText[0]);
var seconds = parseInt(timerText[1]);
return minutes * 60 + seconds;
},
showPlayerPlayButton: function (player) {
player.find(".audio-recorder-player-play").show();
player.find(".audio-recorder-player-stop").hide();
},
showPlayerStopButton: function (player) {
player.find(".audio-recorder-player-play").hide();
player.find(".audio-recorder-player-stop").show();
},
isIOSDevice() {
return navigator.platform != null && ['iPad', 'iPhone', 'iPod'].indexOf(navigator.platform) >= 0;
}
},
templates: {
recorder: "<img src='##domain##/images/audiorecorder/audio-recorder-record.png' class='audio-recorder-record' style='float: left;' title='Grabar archivo de sonido' />" +
"<img src='##domain##/images/audiorecorder/audio-recorder-stop.png' class='audio-recorder-stop' style='float: left;' title='Detener grabacion' />" +
//"<img src='##domain##/images/audiorecorder/audio-recorder-loading.gif' class='audio-recorder-loading' style='float: left;' />" +
"<span class='audio-recorder-loading' style='float: left; font-size: 12px; width: 48px; overflow: hidden; margin-top: 18px;'>Cargando...</span>" +
"<span class='audio-recorder-timer' style='float: left; margin-top: 12px; font-size: 25px; margin-left: 10px;'>0:00</span>" +
"<input type='file' class='audio-recorder-uploader' style='display: none;' accept='audio/*;capture=microphone' />",
player: "<div class='audio-recorder-player'>" +
"<a href='##link##' target='_blank' style='float: left;'>" +
"<img src='##domain##/images/audiorecorder/audio-recorder-play.png' class='audio-recorder-player-play' style='float: left;' onclick='$.audioRecorder.methods.playerPlay(event); ##callbackPlay##' title='Reproducir audio' />" +
"<img src='##domain##/images/audiorecorder/audio-recorder-stop.png' class='audio-recorder-player-stop' style='display: none; float: left;' onclick='$.audioRecorder.methods.playerStop(event); ##callbackStop##' title='Detener audio' />" +
"</a>" +
"<audio src='##link##'></audio>" +
"<span class='audio-recorder-player-current-seek' style='float: left; margin-top: 17px; margin-left: 10px;'>0:00</span>" +
"<div class='audio-recorder-player-progress-bar-parent' style='float: left; margin-top: 14px; margin-left: 3px; width: 204px; height: 22px; box-sizing: border-box; border: 1px solid #AAA; padding: 1px; background-color: #FFF;'>" +
"<div class='audio-recorder-player-progress-bar' style='float: left; height: 18px; background-color: #BCD100;font-size:1px'> </div>" +
"</div>" +
"<span class='audio-recorder-player-total-time' style='float: left; margin-top: 17px; margin-left: 3px;'>##length##</span>" +
"</div>"
}
}
// Privates
//
$.fn.audioRecorder = function (method) {
if ($.audioRecorder.methods[method]) {
return $.audioRecorder.methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return $.audioRecorder.methods.init.apply(this, arguments);
} else {
$.error(method + ' no definido en noteges.audio-recorder.js');
}
};
})(jQuery);
And I call the plugin this way;
$("#" + ID1).audioRecorder({
domain: 'https://example.com',
storageUrl: "/services/uploader/uploadtoazure",
storageAudioContainer: self.azureContainer,
storageAudioPath: self.azureContainerAudio,
callbackAudioSaved: audioSaved,
callbackPlay: null,
id: audioID
});
$("#" + ID2).audioRecorder({
domain: 'https://example.com',
storageUrl: "/services/uploader/uploadtoazure",
storageAudioContainer: self.azureContainer,
storageAudioPath: self.azureContainerAudio,
callbackAudioSaved: audioSaved,
callbackPlay: null,
id: audioID
});
I always thought that everytime I call a plugin a new instance is
generated.
Your plugin function has the context of a new jQuery object instance, but $.audioOptions is not part of that. It is a property on the jQuery global object so a new one isn't created each time the plugin function is called. You can tell this because you keep having to use $.audioOptions.methods to call a method instead of a method call like this.record()
You can refactor your code to create a new object, or a new instance (if changing it to a constructor function), each time the plugin is called. Then you can save the options on the new object/instance, call methods from the it, etc.
Note you could place your methods on the jQuery object instance but that would be polluting it and possibly overwriting jQuery methods.
$.audioRecorder = {
/* other code */
methods: {
init:function(options,$element){
this.options = $.extend(true,{},$.audioRecorder.options,options);
this.options.container = $element;
this.bind();
},
bind: function () {
//uses arrow function to help maintain context and for less code,
//change if supporting older browsers
this.options.container.find(".audio-recorder-record").click(e=>this.record());
}
}
};
$.fn.audioRecorder = function(options){
//if only supposed to use a single element
//otherwise use code in a this.each() callback
var $element = this.first();
var arInstance = Object.create($.audioRecorder.methods);
arInstance.init(options,$element);
$element.data("audioRecorder",arInstance);
return this;
};
Demo
(function($){
$.audioRecorder = {
options:{},
methods: {
init:function(options,$element){
this.options = $.extend(true,{},$.audioRecorder.options,options);
this.options.container = $element;
this.build();
this.bind();
},
build:function(){
this.options.container.append( $.audioRecorder.templates.aTemplate );
},
bind: function () {
this.options.container.find("button").click(e=>this.record());
},
record:function(){
console.log("Record called for id: "+this.options.id);
}
},
templates:{
aTemplate:"<button>Hit to record</button>"
}
};
$.fn.audioRecorder = function(options){
var $element = this.first();
var arInstance = Object.create($.audioRecorder.methods);
arInstance.init(options,$element);
$element.data("audioRecorder",arInstance);
return this;
};
})(jQuery);
jQuery("#container").audioRecorder({
id:"firstRecorder"
});
jQuery("#container1").audioRecorder({
id:"secondRecorder"
});
jQuery("#container2").audioRecorder({
id:"thirdRecorder"
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"></div>
<div id="container1"></div>
<div id="container2"></div>

Need help changing default js toggle state on page load

I'm using a Youtube-TV JS plugin for a client site (https://github.com/Giorgio003/Youtube-TV ). The player loads with a playlist in an open state, and I need to have it load with the toggle closed, showing the array of playlists, can anyone help?
my codepen for the player is here
http://codepen.io/raldesign/pen/OVYXvK
(function(win, doc) {
'use strict';
var apiKey = 'AIzaSyAFMzeux_Eu933wk5U8skMzUzA-urgVgsY';
var YTV = YTV || function(id, opts){
var noop = function(){},
settings = {
apiKey: apiKey,
element: null,
user: null,
channelId: null,
fullscreen: false,
accent: '#fff',
controls: true,
annotations: false,
autoplay: false,
chainVideos: true,
browsePlaylists: false,
playerTheme: 'dark',
listTheme: 'dark',
responsive: false,
playId:'',
sortList: false,
reverseList: false,
shuffleList: false,
wmode: 'opaque',
events: {
videoReady: noop,
stateChange: noop
}
},
cache = {
data: {},
remove: function (url) {
delete cache.data[url];
},
exist: function (url) {
return cache.data.hasOwnProperty(url) && cache.data[url] !== null;
},
get: function (url) {
return cache.data[url];
},
set: function (url, data) {
cache.remove(url);
cache.data[url] = data;
}
},
utils = {
events: {
addEvent: function addEvent(element, eventName, func) {
if (element.addEventListener) {
return element.addEventListener(eventName, func, false);
} else if (element.attachEvent) {
return element.attachEvent("on" + eventName, func);
}
},
removeEvent: function addEvent(element, eventName, func) {
if (element.addEventListener) {
return element.removeEventListener(eventName, func, false);
} else if (element.attachEvent) {
return element.detachEvent("on" + eventName, func);
}
},
prevent: function(e) {
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
}
},
addCSS: function(css){
var head = doc.getElementsByTagName('head')[0],
style = doc.createElement('style');
style.type = 'text/css';
if (style.styleSheet){
style.styleSheet.cssText = css;
} else {
style.appendChild(doc.createTextNode(css));
}
head.appendChild(style);
},
addCommas: function(str){
var x = str.split('.'),
x1 = x[0],
x2 = x.length > 1 ? '.' + x[1] : '',
rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
},
parentUntil: function(el, attr) {
while (el.parentNode) {
if (el.getAttribute && el.getAttribute(attr)){
return el;
}
el = el.parentNode;
}
return null;
},
ajax: {
get: function(url, fn){
if (cache.exist(url)) {
fn.call(this, JSON.parse(cache.get(url)));
} else {
var handle;
if (win.XDomainRequest && !(navigator.appVersion.indexOf("MSIE 8")==-1 || navigator.appVersion.indexOf("MSIE 9")==-1)) { // CORS for IE8,9
handle = new XDomainRequest();
handle.onload = function(){
cache.set(url, handle.responseText);
fn.call(this, JSON.parse(handle.responseText));
if (Object.prototype.hasOwnProperty.call(JSON.parse(handle.responseText), 'error')){
cache.remove(url);
var e = JSON.parse(handle.responseText);
console.log('Youtube-TV Error: Youtube API Response: '+e.error.errors[0].reason+'\n'+ 'Details: '+e.error.errors[0].message);
}
};
} else if (win.XMLHttpRequest){ // Modern Browsers
handle = new XMLHttpRequest();
}
handle.onreadystatechange = function(){
if (handle.readyState === 4 && handle.status === 200){
cache.set(url, handle.responseText);
fn.call(this, JSON.parse(handle.responseText));
} else if (handle.readyState === 4){
var e = JSON.parse(handle.responseText);
console.log('Youtube-TV Error: Youtube API Response: '+e.error.errors[0].reason+'\n'+ 'Details: '+e.error.errors[0].message);
}
};
handle.open("GET",url,true);
handle.send();
}
}
},
endpoints: {
base: 'https://www.googleapis.com/youtube/v3/',
userInfo: function(){
return utils.endpoints.base+'channels?'+settings.cid+'&key='+apiKey+'&part=snippet,contentDetails,statistics';
},
playlistInfo: function(pid){
return utils.endpoints.base+'playlists?id='+pid+'&key='+apiKey+'&maxResults=50&part=snippet';
},
userPlaylists: function(){
return utils.endpoints.base+'playlists?channelId='+settings.channelId+'&key='+apiKey+'&maxResults=50&part=snippet';
},
playlistVids: function(){
return utils.endpoints.base+'playlistItems?playlistId='+settings.pid+'&key='+apiKey+'&maxResults=50&part=contentDetails';
},
videoInfo: function(){
return utils.endpoints.base+'videos?id='+settings.videoString+'&key='+apiKey+'&maxResults=50&part=snippet,contentDetails,status,statistics';
}
},
deepExtend: function(destination, source) {
var property;
for (property in source) {
if (source[property] && source[property].constructor && source[property].constructor === Object) {
destination[property] = destination[property] || {};
utils.deepExtend(destination[property], source[property]);
} else {
destination[property] = source[property];
}
}
return destination;
}
},
prepare = {
youtube: function(){
if(typeof YT=='undefined'){
var tag = doc.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = doc.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
},
build: function(){
if (settings.channelId){
settings.cid = 'id='+settings.channelId;
} else if(settings.user){
settings.cid = 'forUsername='+settings.user;
}
settings.element.className = "ytv-canvas";
if(settings.fullscreen){
settings.element.className += " ytv-full";
}
utils.addCSS( '#'+id+' .ytv-list .ytv-active a{border-left-color: '+(settings.accent)+';}' );
// Responsive CSS
if(settings.responsive){
utils.addCSS('#'+id+' .ytv-video{'
+'position: relative; padding-bottom: 39.4%; /* 16:9 of 70%*/'
+'height: 0; width: 70%;'
+'} #'+id+' .ytv-video iframe{'
+'position: absolute; top: 0; left: 0;'
+'} #'+id+' .ytv-list{'
+'width: 30%;'
+'} #'+id+' .ytv-playlist-open .ytv-arrow{'
+'top: 0px;}'
+'#media only screen and (max-width:992px) {'
+'#'+id+' .ytv-list{'
+'position: relative; display: block;'
+'width: 0; padding-bottom: 40%;'
+'left: auto; right: auto;'
+'top: auto; width: 100%;'
+'} #'+id+' .ytv-video{'
+'position: relative; padding-bottom: 56.25%; /* 16:9 */'
+'height: 0; position: relative;'
+'display: block; left: auto;'
+'right: auto; top: auto; width: 100%;'
+'}}'
);
}
// Temp Scroll Bar fix
if (settings.listTheme == 'dark'){
utils.addCSS( ' #'+id+'.ytv-canvas ::-webkit-scrollbar{border-left: 1px solid #000;}'
+ ' #'+id+'.ytv-canvas ::-webkit-scrollbar-thumb{background: rgba(255,255,255,0.2);}');
}
// Optional Light List Theme
if(settings.listTheme == 'light'){
utils.addCSS( ' #'+id+'.ytv-canvas{background: #ccc;}'
+ ' #'+id+'.ytv-canvas ::-webkit-scrollbar{border-left: 1px solid rgba(28,28,28,0.1);}'
+ ' #'+id+'.ytv-canvas ::-webkit-scrollbar-thumb{background: rgba(28,28,28,0.3);}'
+ ' #'+id+' .ytv-list .ytv-active a{background: rgba(0,0,0,0.2);}'
+ ' #'+id+' .ytv-list a{color: #282828; border-top: 1px solid rgba(0,0,0,0.1); border-bottom: 1px solid rgba(204,204,204,0.5);}'
+ ' #'+id+' .ytv-list a:hover, #'+id+' .ytv-list-header .ytv-playlists a:hover{ background: rgba(0,0,0,0.2);}'
+ ' #'+id+' .ytv-list a:active, #'+id+' .ytv-list-header .ytv-playlists a:active{ background: rgba(0,0,0,0.2);}'
+ ' #'+id+' .ytv-list .ytv-thumb-stroke{outline: 1px solid rgba(0,0,0,0.1);}'
+ ' #'+id+' .ytv-list .ytv-thumb{outline: 1px solid rgba(255,255,255,0.5);}'
+ ' #'+id+' .ytv-list-header{-webkit-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.2); -moz-box-shadow: 0 1px 2px rgba(255, 255, 255, 0.2); box-shadow: 0 1px 2px rgba(255, 255, 255, 0.2);}'
+ ' #'+id+' .ytv-list-header a{background: rgba(0,0,0,0.2);}'
+ ' #'+id+' .ytv-playlists{background: #ccc;}'
);
}
},
userUploads: function(userInfo){
if (userInfo && userInfo.items.length > 0){
settings.pid = userInfo.items[0].contentDetails.relatedPlaylists.uploads;
utils.ajax.get( utils.endpoints.playlistVids(), prepare.compileVideos );
} else console.log ('Youtube-TV Error: API returned no matches for: '+(settings.channelId ? settings.channelId : settings.user)+'\nPlease ensure it was entered correctly and in the appropriate field shown below. \nuser: \'username\' or channelId: \'UCxxxx...\'');
},
selectedPlaylist: function(playlistInfo){
if (playlistInfo && playlistInfo.items.length > 0) {
if (!settings.channelId && !settings.user){
settings.cid = ('id='+(settings.channelId = playlistInfo.items[0].snippet.channelId));
}
settings.currentPlaylist = playlistInfo.items[0].snippet.title;
settings.pid = playlistInfo.items[0].id;
utils.ajax.get( utils.endpoints.playlistVids(), prepare.compileVideos );
} else console.log ('Youtube-TV Error: API returned no matches for playlist(s): '+settings.playlist);
},
compileVideos: function(res){
if (res && res.items.length > 0){
var playlists = res.items,
i;
settings.videoString = '';
for(i=0; i<playlists.length; i++){
settings.videoString += playlists[i].contentDetails.videoId;
if (i<playlists.length-1){ settings.videoString += ',';}
}
utils.ajax.get( utils.endpoints.videoInfo(), prepare.compileList );
} else console.log ('Youtube-TV Error: Empty playlist');
},
playlists: function(res){
if(res && res.items.length > 0){
var list = '<div class="ytv-playlists"><ul>',
playlists = res.items,
i;
for(i=0; i<playlists.length; i++){
var data = {
title: playlists[i].snippet.title,
plid: playlists[i].id,
thumb: playlists[i].snippet.thumbnails.medium.url
};
list += '<a href="#" data-ytv-playlist="'+(data.plid)+'">';
list += '<div class="ytv-thumb"><div class="ytv-thumb-stroke"></div><img src="'+(data.thumb)+'"></div>';
list += '<span>'+(data.title)+'</span>';
list += '</a>';
}
list += '</ul></div>';
var lh = settings.element.getElementsByClassName('ytv-list-header')[0],
headerLink = lh.children[0];
headerLink.href="#";
headerLink.target="";
headerLink.setAttribute('data-ytv-playlist-toggle', 'true');
settings.element.getElementsByClassName('ytv-list-header')[0].innerHTML += list;
lh.className += ' ytv-has-playlists';
} else console.log ('Youtube-TV Error: Returned no playlists');
},
compileList: function(data){
if(data && data.items.length > 0){
utils.ajax.get( utils.endpoints.userInfo(), function(userInfo){
var list = '',
user = {
title: userInfo.items[0].snippet.title,
url: '//youtube.com/channel/'+userInfo.items[0].id,
thumb: userInfo.items[0].snippet.thumbnails['default'].url,
summary: userInfo.items[0].snippet.description,
subscribers: userInfo.items[0].statistics.subscriberCount,
views: userInfo.items[0].statistics.viewCount
},
videos = data.items,
first = true,
i;
settings.channelId = userInfo.items[0].id;
if(settings.currentPlaylist) user.title += ' · '+(settings.currentPlaylist);
if (settings.sortList) videos.sort(function(a,b){if(a.snippet.publishedAt > b.snippet.publishedAt) return -1;if(a.snippet.publishedAt < b.snippet.publishedAt) return 1;return 0;});
if (settings.reverseList) videos.reverse();
if (settings.shuffleList) {
videos = function (){for(var j, x, i = videos.length; i; j = Math.floor(Math.random() * i), x = videos[--i], videos[i] = videos[j], videos[j] = x);return videos;}();
}
list += '<div class="ytv-list-header">';
list += '<a href="'+(user.url)+'" target="_blank">';
list += '<img src="'+(user.thumb)+'">';
list += '<span><i class="ytv-arrow down"></i>'+(user.title)+'</span>';
list += '</a>';
list += '</div>';
list += '<div class="ytv-list-inner"><ul>';
for(i=0; i<videos.length; i++){
if(videos[i].status.embeddable){
var video = {
title: videos[i].snippet.title,
slug: videos[i].id,
link: 'https://www.youtube.com/watch?v='+videos[i].id,
published: videos[i].snippet.publishedAt,
stats: videos[i].statistics,
duration: (videos[i].contentDetails.duration),
thumb: videos[i].snippet.thumbnails.medium.url
};
var durationString = video.duration.match(/[0-9]+[HMS]/g);
var h = 0, m = 0, s = 0, time = '';
durationString.forEach(function (duration) {
var unit = duration.charAt(duration.length-1);
var amount = parseInt(duration.slice(0,-1));
switch (unit) {
case 'H': h = (amount > 9 ? '' + amount : '0' + amount); break;
case 'M': m = (amount > 9 ? '' + amount : '0' + amount); break;
case 'S': s = (amount > 9 ? '' + amount : '0' + amount); break;
}
});
if (h){ time += h+':';}
if (m){ time += m+':';} else { time += '00:';}
if (s){ time += s;} else { time += '00';}
var isFirst = '';
if(settings.playId==video.slug){
isFirst = ' class="ytv-active"';
first = video.slug;
} else if(first===true){
first = video.slug;
}
list += '<li'+isFirst+'><a href="#" data-ytv="'+(video.slug)+'" class="ytv-clear">';
list += '<div class="ytv-thumb"><div class="ytv-thumb-stroke"></div><span>'+(time)+'</span><img src="'+(video.thumb)+'"></div>';
list += '<div class="ytv-content"><b>'+(video.title)+'</b>';
if (video.stats)
{
list+='</b><span class="ytv-views">'+utils.addCommas(video.stats.viewCount)+' Views</span>';
}
list += '</div></a></li>';
}
}
list += '</ul></div>';
settings.element.innerHTML = '<div class="ytv-relative"><div class="ytv-video"><div id="ytv-video-player"></div></div><div class="ytv-list">'+list+'</div></div>';
if(settings.element.getElementsByClassName('ytv-active').length===0){
settings.element.getElementsByTagName('li')[0].className = "ytv-active";
}
var active = settings.element.getElementsByClassName('ytv-active')[0];
active.parentNode.parentNode.scrollTop = active.offsetTop;
action.logic.loadVideo(first, settings.autoplay);
if (settings.playlist){
utils.ajax.get( utils.endpoints.playlistInfo(settings.playlist), prepare.playlists );
} else if(settings.browsePlaylists){
utils.ajax.get( utils.endpoints.userPlaylists(), prepare.playlists );
}
});
} else console.log ('Youtube-TV Error: Empty video list');
}
},
action = {
logic: {
playerStateChange: function(d){
console.log(d);
},
loadVideo: function(slug, autoplay){
var house = settings.element.getElementsByClassName('ytv-video')[0];
var counter = settings.element.getElementsByClassName('ytv-video-playerContainer').length;
house.innerHTML = '<div id="ytv-video-player'+id+counter+'" class="ytv-video-playerContainer"></div>';
cache.player = new YT.Player('ytv-video-player'+id+counter, {
videoId: slug,
events: {
onReady: settings.events.videoReady,
onStateChange: function(e){
if( (e.target.getPlayerState()===0) && settings.chainVideos ){
var ns = settings.element.getElementsByClassName('ytv-active')[0].nextSibling,
link = ns.children[0];
link.click();
}
settings.events.stateChange.call(this, e);
}
},
playerVars: {
enablejsapi: 1,
origin: doc.domain,
controls: settings.controls ? 1 : 0,
rel: 0,
showinfo: 0,
iv_load_policy: settings.annotations ? '' : 3,
autoplay: autoplay ? 1 : 0,
theme: settings.playerTheme,
wmode: settings.wmode
}
});
}
},
endpoints: {
videoClick: function(e){
var target = utils.parentUntil(e.target ? e.target : e.srcElement, 'data-ytv');
if(target){
if(target.getAttribute('data-ytv')){
// Load Video
utils.events.prevent(e);
var activeEls = settings.element.getElementsByClassName('ytv-active'),
i;
for(i=0; i<activeEls.length; i++){
activeEls[i].className="";
}
target.parentNode.className="ytv-active";
action.logic.loadVideo(target.getAttribute('data-ytv'), true);
}
}
},
playlistToggle: function(e){
var target = utils.parentUntil(e.target ? e.target : e.srcElement, 'data-ytv-playlist-toggle');
if(target && target.getAttribute('data-ytv-playlist-toggle')){
// Toggle Playlist
utils.events.prevent(e);
var lh = settings.element.getElementsByClassName('ytv-list-header')[0];
if(lh.className.indexOf('ytv-playlist-open')===-1){
lh.className += ' ytv-playlist-open';
} else {
lh.className = lh.className.replace(' ytv-playlist-open', '');
}
}
},
playlistClick: function(e){
var target = utils.parentUntil(e.target ? e.target : e.srcElement, 'data-ytv-playlist');
if(target && target.getAttribute('data-ytv-playlist')){
// Load Playlist
utils.events.prevent(e);
settings.pid = target.getAttribute('data-ytv-playlist');
target.children[1].innerHTML = 'Loading...';
utils.ajax.get( utils.endpoints.playlistInfo(settings.pid), function(res){
var lh = settings.element.getElementsByClassName('ytv-list-header')[0];
lh.className = lh.className.replace(' ytv-playlist-open', '');
prepare.selectedPlaylist(res);
});
}
}
},
bindEvents: function(){
utils.events.addEvent( settings.element, 'click', action.endpoints.videoClick );
utils.events.addEvent( settings.element, 'click', action.endpoints.playlistToggle );
utils.events.addEvent( settings.element, 'click', action.endpoints.playlistClick );
}
},
initialize = function(id, opts){
utils.deepExtend(settings, opts);
if(settings.apiKey.length===0){
alert("Missing APIkey in settings or as global vaiable.");
}
apiKey = settings.apiKey;
settings.element = (typeof id==='string') ? doc.getElementById(id) : id;
if(settings.element && (settings.user || settings.channelId || settings.playlist)){
prepare.youtube();
prepare.build();
action.bindEvents();
if (settings.playlist) {
utils.ajax.get( utils.endpoints.playlistInfo(settings.playlist), prepare.selectedPlaylist );
} else {
utils.ajax.get( utils.endpoints.userInfo(), prepare.userUploads );
}
} else console.log ('Youtube-TV Error: Missing either user, channelId, or playlist');
};
/* Public */
this.destroy = function(){
utils.events.removeEvent( settings.element, 'click', action.endpoints.videoClick );
utils.events.removeEvent( settings.element, 'click', action.endpoints.playlistToggle );
utils.events.removeEvent( settings.element, 'click', action.endpoints.playlistClick );
settings.element.className = '';
settings.element.innerHTML = '';
};
this.fullscreen = {
state: function(){
return (settings.element.className).indexOf('ytv-full') !== -1;
},
enter: function(){
if( (settings.element.className).indexOf('ytv-full') === -1 ){
settings.element.className += 'ytv-full';
}
},
exit: function(){
if( (settings.element.className).indexOf('ytv-full') !== -1 ){
settings.element.className = (settings.element.className).replace('ytv-full', '');
}
}
};
initialize(id, opts);
};
if ((typeof module !== 'undefined') && module.exports) {
module.exports = YTV;
}
if (typeof ender === 'undefined') {
this.YTV = YTV;
}
if ((typeof define === "function") && define.amd) {
define("YTV", [], function() {
return YTV;
});
}
if ((typeof jQuery !== 'undefined')) {
jQuery.fn.extend({
ytv: function(options) {
return this.each(function() {
new YTV(this.id, options);
});
}
});
}
}).call(this, window, document);
Replace this
list += '<div class="ytv-list-header">';
with
list += '<div class="ytv-list-header ytv-playlist-open">';
There is two playlist one is "list of all playlists". And other is "list of videos in a playlist".
"ytv-playlist-open" indicate the open status for "list of all playlist". So when it is added it will close "videos in a playlist" and show "list of all playlist" which you want to show there.

Autocomplete Textbox fetching suggestions from database?

I have created 2 autosuggest textboxes in which one is fetching data from server-side and another is fetching data from client-side.But server-side textbox is not working.Can anyone point out the error in my code.
Following is my HTML Code:
<html>
<link type="text/css" rel="stylesheet" media="all" href="jquery-ui-1.8.9.custom.css" />
<script type="text/javascript" src="jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="jquery-ui-1.8.9.custom.min.js"></script>
<script type="text/javascript" src="languages.js"></script>
<body>
<label for="languagesClientInput">Select Language(client-side): </label>
<input id="languagesClientInput" />
<br />
<label for="languagesServerInput">Select Language (server-side): </label>
<input id="languagesServerInput" />
</body>
</html>
Following is Js Code:
$(function() {
var languages = [
"C",
"C++",
"Core Java",
"Advance Java",
"PHP",
".NET",
"XML",
"HTML",
"Javascript",
"jQuery",
"JSON",
"Ajax",
"C#",
"ABC ALGOL",
"ADA",
"ABLE",
"COBOL",
"BLUE",
"Pearl",
"Python",
"Oracle",
"Haskell",
"BASIC",
"BeanShell",
"Bliss",
"BETA",
"GOTRAN",
"FORTRAN",
"Focal",
"Genie",
"GOAL",
"GROOVY",
"JOSS",
"JEAN",
"JOVIAL",
"JOY",
"Maple",
"MATLAB",
"MORTAN",
"MUMPS",
"Miranda",
"NetRexx",
"NPL",
"NXT-G"
];
$("#languagesClientInput").autocomplete( { source: languages });
$("#languagesServerInput").autocomplete( { source: "languages.php" });
});
Following is Php Code:
<?php
$searchTerm = $_GET['term'];
$languages = array(
"C",
"C++",
"Core Java",
"Advance Java",
"PHP",
".NET",
"XML",
"HTML",
"Javascript",
"jQuery",
"JSON",
"Ajax",
"C#",
"ABC ALGOL",
"ADA",
"ABLE",
"COBOL",
"BLUE",
"Pearl",
"Python",
"Oracle",
"Haskell",
"BASIC",
"BeanShell",
"Bliss",
"BETA",
"GOTRAN",
"FORTRAN",
"Focal",
"Genie",
"GOAL",
"GROOVY",
"JOSS",
"JEAN",
"JOVIAL",
"JOY",
"Maple",
"MATLAB",
"MORTAN",
"MUMPS",
"Miranda",
"NetRexx",
"NPL",
"NXT-G"
);
function filter($language) {
global $searchTerm;
return stripos($language, $searchTerm) !== false;
}
print(json_encode(array_values(array_filter($languages, "filter"))));
?>
The array_filter function fails. If you remove it you will get the data you need.
I actually think you have made a mistake there by writing array_filter instead of just filter to call the function you wrote above.
Run this command in MySQL database;
CREATE TABLE `tag` (
`id` int(20) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;
INSERT INTO `tag` (`id`, `name`) VALUES
(1, 'php'),
(2, 'php frameword'),
(3, 'php tutorial'),
(4, 'jquery'),
(5, 'ajax'),
(6, 'mysql'),
(7, 'wordpress'),
(8, 'wordpress theme'),
(9, 'xml');
index.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Auto Complete Input box</title>
<link rel="stylesheet" type="text/css" href="jquery.autocomplete.css" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.autocomplete.js"></script>
<script>
$(document).ready(function(){
$("#tag").autocomplete("autocomplete.php", {
selectFirst: true
});
});
</script>
</head>
<body>
<label>Tag:</label>
<input name="tag" type="text" id="tag" size="20"/>
</body>
</html>
autocomplete.php
<?php
$q=$_GET['q'];
$my_data=mysql_real_escape_string($q);
$mysqli=mysqli_connect('localhost','root','','autofield') or die("Database Error");
$sql="SELECT name FROM tag WHERE name LIKE '%$my_data%' ORDER BY name";
$result = mysqli_query($mysqli,$sql) or die(mysqli_error());
if($result)
{
while($row=mysqli_fetch_array($result))
{
echo $row['name']."\n";
}
}
?>
jquery.autocomplete.css
.ac_results {
padding: 0px;
border: 1px solid black;
background-color: white;
overflow: hidden;
z-index: 99999;
}
.ac_results ul {
width: 100%;
list-style-position: outside;
list-style: none;
padding: 0;
margin: 0;
}
.ac_results li {
margin: 0px;
padding: 2px 5px;
cursor: default;
display: block;
/*
if width will be 100% horizontal scrollbar will apear
when scroll mode will be used
*/
/*width: 100%;*/
font: menu;
font-size: 12px;
/*
it is very important, if line-height not setted or setted
in relative units scroll will be broken in firefox
*/
line-height: 16px;
overflow: hidden;
}
.ac_loading {
background: white url('indicator.gif') right center no-repeat;
}
.ac_odd {
background-color: #eee;
}
.ac_over {
background-color: #0A246A;
color: white;
}
jquery.autocomplete.js
/*
* jQuery Autocomplete plugin 1.1
*
* Copyright (c) 2009 Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $
*/
;(function($) {
$.fn.extend({
autocomplete: function(urlOrData, options) {
var isUrl = typeof urlOrData == "string";
options = $.extend({}, $.Autocompleter.defaults, {
url: isUrl ? urlOrData : null,
data: isUrl ? null : urlOrData,
delay: isUrl ? $.Autocompleter.defaults.delay : 10,
max: options && !options.scroll ? 10 : 150
}, options);
// if highlight is set to false, replace it with a do-nothing function
options.highlight = options.highlight || function(value) { return value; };
// if the formatMatch option is not specified, then use formatItem for backwards compatibility
options.formatMatch = options.formatMatch || options.formatItem;
return this.each(function() {
new $.Autocompleter(this, options);
});
},
result: function(handler) {
return this.bind("result", handler);
},
search: function(handler) {
return this.trigger("search", [handler]);
},
flushCache: function() {
return this.trigger("flushCache");
},
setOptions: function(options){
return this.trigger("setOptions", [options]);
},
unautocomplete: function() {
return this.trigger("unautocomplete");
}
});
$.Autocompleter = function(input, options) {
var KEY = {
UP: 38,
DOWN: 40,
DEL: 46,
TAB: 9,
RETURN: 13,
ESC: 27,
COMMA: 188,
PAGEUP: 33,
PAGEDOWN: 34,
BACKSPACE: 8
};
// Create $ object for input element
var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
var timeout;
var previousValue = "";
var cache = $.Autocompleter.Cache(options);
var hasFocus = 0;
var lastKeyPressCode;
var config = {
mouseDownOnSelect: false
};
var select = $.Autocompleter.Select(options, input, selectCurrent, config);
var blockSubmit;
// prevent form submit in opera when selecting with return key
$.browser.opera && $(input.form).bind("submit.autocomplete", function() {
if (blockSubmit) {
blockSubmit = false;
return false;
}
});
// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
// a keypress means the input has focus
// avoids issue where input had focus before the autocomplete was applied
hasFocus = 1;
// track last key pressed
lastKeyPressCode = event.keyCode;
switch(event.keyCode) {
case KEY.UP:
event.preventDefault();
if ( select.visible() ) {
select.prev();
} else {
onChange(0, true);
}
break;
case KEY.DOWN:
event.preventDefault();
if ( select.visible() ) {
select.next();
} else {
onChange(0, true);
}
break;
case KEY.PAGEUP:
event.preventDefault();
if ( select.visible() ) {
select.pageUp();
} else {
onChange(0, true);
}
break;
case KEY.PAGEDOWN:
event.preventDefault();
if ( select.visible() ) {
select.pageDown();
} else {
onChange(0, true);
}
break;
// matches also semicolon
case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
case KEY.TAB:
case KEY.RETURN:
if( selectCurrent() ) {
// stop default to prevent a form submit, Opera needs special handling
event.preventDefault();
blockSubmit = true;
return false;
}
break;
case KEY.ESC:
select.hide();
break;
default:
clearTimeout(timeout);
timeout = setTimeout(onChange, options.delay);
break;
}
}).focus(function(){
// track whether the field has focus, we shouldn't process any
// results if the field no longer has focus
hasFocus++;
}).blur(function() {
hasFocus = 0;
if (!config.mouseDownOnSelect) {
hideResults();
}
}).click(function() {
// show select when clicking in a focused field
if ( hasFocus++ > 1 && !select.visible() ) {
onChange(0, true);
}
}).bind("search", function() {
// TODO why not just specifying both arguments?
var fn = (arguments.length > 1) ? arguments[1] : null;
function findValueCallback(q, data) {
var result;
if( data && data.length ) {
for (var i=0; i < data.length; i++) {
if( data[i].result.toLowerCase() == q.toLowerCase() ) {
result = data[i];
break;
}
}
}
if( typeof fn == "function" ) fn(result);
else $input.trigger("result", result && [result.data, result.value]);
}
$.each(trimWords($input.val()), function(i, value) {
request(value, findValueCallback, findValueCallback);
});
}).bind("flushCache", function() {
cache.flush();
}).bind("setOptions", function() {
$.extend(options, arguments[1]);
// if we've updated the data, repopulate
if ( "data" in arguments[1] )
cache.populate();
}).bind("unautocomplete", function() {
select.unbind();
$input.unbind();
$(input.form).unbind(".autocomplete");
});
function selectCurrent() {
var selected = select.selected();
if( !selected )
return false;
var v = selected.result;
previousValue = v;
if ( options.multiple ) {
var words = trimWords($input.val());
if ( words.length > 1 ) {
var seperator = options.multipleSeparator.length;
var cursorAt = $(input).selection().start;
var wordAt, progress = 0;
$.each(words, function(i, word) {
progress += word.length;
if (cursorAt <= progress) {
wordAt = i;
return false;
}
progress += seperator;
});
words[wordAt] = v;
// TODO this should set the cursor to the right position, but it gets overriden somewhere
//$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
v = words.join( options.multipleSeparator );
}
v += options.multipleSeparator;
}
$input.val(v);
hideResultsNow();
$input.trigger("result", [selected.data, selected.value]);
return true;
}
function onChange(crap, skipPrevCheck) {
if( lastKeyPressCode == KEY.DEL ) {
select.hide();
return;
}
var currentValue = $input.val();
if ( !skipPrevCheck && currentValue == previousValue )
return;
previousValue = currentValue;
currentValue = lastWord(currentValue);
if ( currentValue.length >= options.minChars) {
$input.addClass(options.loadingClass);
if (!options.matchCase)
currentValue = currentValue.toLowerCase();
request(currentValue, receiveData, hideResultsNow);
} else {
stopLoading();
select.hide();
}
};
function trimWords(value) {
if (!value)
return [""];
if (!options.multiple)
return [$.trim(value)];
return $.map(value.split(options.multipleSeparator), function(word) {
return $.trim(value).length ? $.trim(word) : null;
});
}
function lastWord(value) {
if ( !options.multiple )
return value;
var words = trimWords(value);
if (words.length == 1)
return words[0];
var cursorAt = $(input).selection().start;
if (cursorAt == value.length) {
words = trimWords(value)
} else {
words = trimWords(value.replace(value.substring(cursorAt), ""));
}
return words[words.length - 1];
}
// fills in the input box w/the first match (assumed to be the best match)
// q: the term entered
// sValue: the first matching result
function autoFill(q, sValue){
// autofill in the complete box w/the first match as long as the user hasn't entered in more data
// if the last user key pressed was backspace, don't autofill
if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
// fill in the value (keep the case the user has typed)
$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
// select the portion of the value not typed by the user (so the next character will erase)
$(input).selection(previousValue.length, previousValue.length + sValue.length);
}
};
function hideResults() {
clearTimeout(timeout);
timeout = setTimeout(hideResultsNow, 200);
};
function hideResultsNow() {
var wasVisible = select.visible();
select.hide();
clearTimeout(timeout);
stopLoading();
if (options.mustMatch) {
// call search and run callback
$input.search(
function (result){
// if no value found, clear the input box
if( !result ) {
if (options.multiple) {
var words = trimWords($input.val()).slice(0, -1);
$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
}
else {
$input.val( "" );
$input.trigger("result", null);
}
}
}
);
}
};
function receiveData(q, data) {
if ( data && data.length && hasFocus ) {
stopLoading();
select.display(data, q);
autoFill(q, data[0].value);
select.show();
} else {
hideResultsNow();
}
};
function request(term, success, failure) {
if (!options.matchCase)
term = term.toLowerCase();
var data = cache.load(term);
// recieve the cached data
if (data && data.length) {
success(term, data);
// if an AJAX url has been supplied, try loading the data now
} else if( (typeof options.url == "string") && (options.url.length > 0) ){
var extraParams = {
timestamp: +new Date()
};
$.each(options.extraParams, function(key, param) {
extraParams[key] = typeof param == "function" ? param() : param;
});
$.ajax({
// try to leverage ajaxQueue plugin to abort previous requests
mode: "abort",
// limit abortion to this input
port: "autocomplete" + input.name,
dataType: options.dataType,
url: options.url,
data: $.extend({
q: lastWord(term),
limit: options.max
}, extraParams),
success: function(data) {
var parsed = options.parse && options.parse(data) || parse(data);
cache.add(term, parsed);
success(term, parsed);
}
});
} else {
// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
select.emptyList();
failure(term);
}
};
function parse(data) {
var parsed = [];
var rows = data.split("\n");
for (var i=0; i < rows.length; i++) {
var row = $.trim(rows[i]);
if (row) {
row = row.split("|");
parsed[parsed.length] = {
data: row,
value: row[0],
result: options.formatResult && options.formatResult(row, row[0]) || row[0]
};
}
}
return parsed;
};
function stopLoading() {
$input.removeClass(options.loadingClass);
};
};
$.Autocompleter.defaults = {
inputClass: "ac_input",
resultsClass: "ac_results",
loadingClass: "ac_loading",
minChars: 1,
delay: 400,
matchCase: false,
matchSubset: true,
matchContains: false,
cacheLength: 10,
max: 100,
mustMatch: false,
extraParams: {},
selectFirst: true,
formatItem: function(row) { return row[0]; },
formatMatch: null,
autoFill: false,
width: 0,
multiple: false,
multipleSeparator: ", ",
highlight: function(value, term) {
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
},
scroll: true,
scrollHeight: 180
};
$.Autocompleter.Cache = function(options) {
var data = {};
var length = 0;
function matchSubset(s, sub) {
if (!options.matchCase)
s = s.toLowerCase();
var i = s.indexOf(sub);
if (options.matchContains == "word"){
i = s.toLowerCase().search("\\b" + sub.toLowerCase());
}
if (i == -1) return false;
return i == 0 || options.matchContains;
};
function add(q, value) {
if (length > options.cacheLength){
flush();
}
if (!data[q]){
length++;
}
data[q] = value;
}
function populate(){
if( !options.data ) return false;
// track the matches
var stMatchSets = {},
nullData = 0;
// no url was specified, we need to adjust the cache length to make sure it fits the local data store
if( !options.url ) options.cacheLength = 1;
// track all options for minChars = 0
stMatchSets[""] = [];
// loop through the array and create a lookup structure
for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
var rawValue = options.data[i];
// if rawValue is a string, make an array otherwise just reference the array
rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
var value = options.formatMatch(rawValue, i+1, options.data.length);
if ( value === false )
continue;
var firstChar = value.charAt(0).toLowerCase();
// if no lookup array for this character exists, look it up now
if( !stMatchSets[firstChar] )
stMatchSets[firstChar] = [];
// if the match is a string
var row = {
value: value,
data: rawValue,
result: options.formatResult && options.formatResult(rawValue) || value
};
// push the current match into the set list
stMatchSets[firstChar].push(row);
// keep track of minChars zero items
if ( nullData++ < options.max ) {
stMatchSets[""].push(row);
}
};
// add the data items to the cache
$.each(stMatchSets, function(i, value) {
// increase the cache size
options.cacheLength++;
// add to the cache
add(i, value);
});
}
// populate any existing data
setTimeout(populate, 25);
function flush(){
data = {};
length = 0;
}
return {
flush: flush,
add: add,
populate: populate,
load: function(q) {
if (!options.cacheLength || !length)
return null;
/*
* if dealing w/local data and matchContains than we must make sure
* to loop through all the data collections looking for matches
*/
if( !options.url && options.matchContains ){
// track all matches
var csub = [];
// loop through all the data grids for matches
for( var k in data ){
// don't search through the stMatchSets[""] (minChars: 0) cache
// this prevents duplicates
if( k.length > 0 ){
var c = data[k];
$.each(c, function(i, x) {
// if we've got a match, add it to the array
if (matchSubset(x.value, q)) {
csub.push(x);
}
});
}
}
return csub;
} else
// if the exact item exists, use it
if (data[q]){
return data[q];
} else
if (options.matchSubset) {
for (var i = q.length - 1; i >= options.minChars; i--) {
var c = data[q.substr(0, i)];
if (c) {
var csub = [];
$.each(c, function(i, x) {
if (matchSubset(x.value, q)) {
csub[csub.length] = x;
}
});
return csub;
}
}
}
return null;
}
};
};
$.Autocompleter.Select = function (options, input, select, config) {
var CLASSES = {
ACTIVE: "ac_over"
};
var listItems,
active = -1,
data,
term = "",
needsInit = true,
element,
list;
// Create results
function init() {
if (!needsInit)
return;
element = $("<div/>")
.hide()
.addClass(options.resultsClass)
.css("position", "absolute")
.appendTo(document.body);
list = $("<ul/>").appendTo(element).mouseover( function(event) {
if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
$(target(event)).addClass(CLASSES.ACTIVE);
}
}).click(function(event) {
$(target(event)).addClass(CLASSES.ACTIVE);
select();
// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
input.focus();
return false;
}).mousedown(function() {
config.mouseDownOnSelect = true;
}).mouseup(function() {
config.mouseDownOnSelect = false;
});
if( options.width > 0 )
element.css("width", options.width);
needsInit = false;
}
function target(event) {
var element = event.target;
while(element && element.tagName != "LI")
element = element.parentNode;
// more fun with IE, sometimes event.target is empty, just ignore it then
if(!element)
return [];
return element;
}
function moveSelect(step) {
listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
movePosition(step);
var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
if(options.scroll) {
var offset = 0;
listItems.slice(0, active).each(function() {
offset += this.offsetHeight;
});
if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
} else if(offset < list.scrollTop()) {
list.scrollTop(offset);
}
}
};
function movePosition(step) {
active += step;
if (active < 0) {
active = listItems.size() - 1;
} else if (active >= listItems.size()) {
active = 0;
}
}
function limitNumberOfItems(available) {
return options.max && options.max < available
? options.max
: available;
}
function fillList() {
list.empty();
var max = limitNumberOfItems(data.length);
for (var i=0; i < max; i++) {
if (!data[i])
continue;
var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
if ( formatted === false )
continue;
var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
$.data(li, "ac_data", data[i]);
}
listItems = list.find("li");
if ( options.selectFirst ) {
listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
active = 0;
}
// apply bgiframe if available
if ( $.fn.bgiframe )
list.bgiframe();
}
return {
display: function(d, q) {
init();
data = d;
term = q;
fillList();
},
next: function() {
moveSelect(1);
},
prev: function() {
moveSelect(-1);
},
pageUp: function() {
if (active != 0 && active - 8 < 0) {
moveSelect( -active );
} else {
moveSelect(-8);
}
},
pageDown: function() {
if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
moveSelect( listItems.size() - 1 - active );
} else {
moveSelect(8);
}
},
hide: function() {
element && element.hide();
listItems && listItems.removeClass(CLASSES.ACTIVE);
active = -1;
},
visible : function() {
return element && element.is(":visible");
},
current: function() {
return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
},
show: function() {
var offset = $(input).offset();
element.css({
width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
top: offset.top + input.offsetHeight,
left: offset.left
}).show();
if(options.scroll) {
list.scrollTop(0);
list.css({
maxHeight: options.scrollHeight,
overflow: 'auto'
});
if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
var listHeight = 0;
listItems.each(function() {
listHeight += this.offsetHeight;
});
var scrollbarsVisible = listHeight > options.scrollHeight;
list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
if (!scrollbarsVisible) {
// IE doesn't recalculate width when scrollbar disappears
listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
}
}
}
},
selected: function() {
var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
return selected && selected.length && $.data(selected[0], "ac_data");
},
emptyList: function (){
list && list.empty();
},
unbind: function() {
element && element.remove();
}
};
};
$.fn.selection = function(start, end) {
if (start !== undefined) {
return this.each(function() {
if( this.createTextRange ){
var selRange = this.createTextRange();
if (end === undefined || start == end) {
selRange.move("character", start);
selRange.select();
} else {
selRange.collapse(true);
selRange.moveStart("character", start);
selRange.moveEnd("character", end);
selRange.select();
}
} else if( this.setSelectionRange ){
this.setSelectionRange(start, end);
} else if( this.selectionStart ){
this.selectionStart = start;
this.selectionEnd = end;
}
});
}
var field = this[0];
if ( field.createTextRange ) {
var range = document.selection.createRange(),
orig = field.value,
teststring = "<->",
textLength = range.text.length;
range.text = teststring;
var caretAt = field.value.indexOf(teststring);
field.value = orig;
this.selection(caretAt, caretAt + textLength);
return {
start: caretAt,
end: caretAt + textLength
}
} else if( field.selectionStart !== undefined ){
return {
start: field.selectionStart,
end: field.selectionEnd
}
}
};
})(jQuery);
Download jquery.min.js and rename it to jquery.js
Now open index.php in your localhost/server and test it. Follow the similar method with your wordlist.
You don't need the array_values function. This worked for me:
// languages.php
<?php
function filter($language) {
global $searchTerm;
return stripos( $language, $searchTerm ) !== false;
}
$searchTerm = $_GET['term'];
$languages = array(
"C",
"C++",
"Core Java",
"Advance Java",
"PHP",
".NET",
"XML",
"HTML",
"Javascript",
"jQuery",
"JSON",
"Ajax",
"C#",
"ABC ALGOL",
"ADA",
"ABLE",
"COBOL",
"BLUE",
"Pearl",
"Python",
"Oracle",
"Haskell",
"BASIC",
"BeanShell",
"Bliss",
"BETA",
"GOTRAN",
"FORTRAN",
"Focal",
"Genie",
"GOAL",
"GROOVY",
"JOSS",
"JEAN",
"JOVIAL",
"JOY",
"Maple",
"MATLAB",
"MORTAN",
"MUMPS",
"Miranda",
"NetRexx",
"NPL",
"NXT-G"
);
$jsonData = array_filter( $languages, "filter" );
print( json_encode( $jsonData ) );
?>

Categories

Resources