I am using ajax to do some mathematical calculations. The controller sends the correct response back but the data is not being displayed (when I try to do console.log(data) after success) and instead alerts an error message - "Error : SyntaxError: Unexpected token { in JSON at position 4". I have been debugging since yesterday to no success.
Here is the JSON being returned
{
mydata: {
items: [
20.68
],
sub_total: 20,
tax_total: 0.68,
grand_total: 20.68
}
}
This is the Ajax function
function totalItem() {
$.ajax({
url: '{{ url("finance/items/totalItem") }}',
type: 'POST',
dataType: 'JSON',
data: $('#items input[type=\'text\'],#items input[type=\'hidden\'], #items textarea, #items select'),
headers: { 'X-CSRF-TOKEN': csrf },
success: function(data) {
if (data) {
$.each( data.items, function( key, value ) {
console.log(data);
//$('#item-total-' + key).html(value);
$('#item-total-' + key).val(value);
});
$('#sub-total').html(data.sub_total);
$('#tax-total').html(data.tax_total);
$('#grand-total').html(data.grand_total);
}
},
error:function (xhr, ajaxOptions, thrownError) {
alert("Error : "+thrownError);
}
});
}
My Controller
public function totalItem(Request $request)
{
//
//$input_items = request('item');
$input_items = $request->item;
$mydata = new \stdClass;
$sub_total = 0;
$tax_total = 0;
//$tax = 0;
$items = array();
if ($input_items) {
foreach ($input_items as $key => $item) {
//return response()->json($item['tax_id']);
$item_tax_total = 0;
$price = isset($item['price']) ? $item['price'] : 0;
$qty = isset($item['quantity']) ? $item['quantity'] : 0;
$item_sub_total = ($price * $qty);
//$item_sub_total = (2 * 2);
if (isset($item['tax_id'])) {
$tax = Tax::find($item['tax_id']);
$rate = isset($tax->rate) ? $tax->rate : 0;
$item_tax_total = (($price * $qty) / 100) * $rate;
}
$sub_total += $item_sub_total;
$tax_total += $item_tax_total;
$total = $item_sub_total + $item_tax_total;
//$items[$key] = money($total, $currency_code, true)->format();
$items[$key] = $total;
//return response()->json($tax);
//return response()->json($sub_total);
}
}
$mydata->items = $items;
$mydata->sub_total = $sub_total; //money($sub_total, $currency_code, true)->format();
$mydata->tax_total = $tax_total; //money($tax_total, $currency_code, true)->format();
$grand_total = $sub_total + $tax_total;
$mydata->grand_total = $grand_total; //money($grand_total, $currency_code, true)->format();
return response()->json(['mydata' => $mydata]);
}
}
Missing double quotes. The JSON should be
{
"mydata": {
"items": [
20.68
],
"sub_total": 20,
"tax_total": 0.68,
"grand_total": 20.68
}
}
Related
class ProductInfoDetailsViewModel {
constructor(parent, productInfoWindowId, inventoryId, productId, supplierId, store) {
this._parent = parent;
this._created = false;
this._productInfoWindowId = productInfoWindowId;
this._inventoryId = inventoryId;
this._productId = productId;
this._supplierId = supplierId;
this._store = store;
}
_getMvvmData(inventoryId, productId, supplierId) {
return new Promise(function (resolve, reject) {
$.ajax({
url: '/ProductRowInfoSite/GetInventoryControl',
data: {
'inventoryId': inventoryId,
'productId': productId,
'supplierId': supplierId,
},
dataType: 'json', // "jsonp" is required for cross-domain requests; use "json" for same-domain requests
success: function (result) {
resolve(result);
},
error: function (jqXHR, textStatus, errorThrown) {
reject([jqXHR, textStatus, errorThrown]);
},
type: 'POST',
});
});
}
async create() {
let self = this;
let userStore = new UserStore();
//productInfoTextGrid
this._productInfoDetailsViewModel = kendo.observable({
value: {},
close: function () {
//$("#generalProductInfoWindow").data("kendoWindow").close();
//closeWindow();
},
not: function (value) {
return !this.get(value);
},
save: function (e) {
let productInfoTextGrid = $(self._productInfoWindowId + ' ' + '#productInfoTextGrid').data('kendoGrid');
/* productInfoTextGrid.saveChanges();*/
let orderUnitsGrid = $(self._productInfoWindowId + ' ' + '#orderUnitsGrid').data('kendoGrid');
let selectedRefHistProd = null;
try {
selectedRefHistProd = this.get('value.SelectedRefHistProd').ProductId;
} catch (error) {
// may be set to null and that's fine/TK.
}
var data = {
ProductId: self._productId,
InventoryId: self._inventoryId,
SupplierId: self._supplierId,
Fmean: this.get('value.Fmean'),
FMAD: this.get('value.FMAD'),
FTrend: this.get('value.FTrend'),
SelectedSeason: this.get('value.SelectedSeason').SeasonId,
MinQuantity: this.get('value.MinQuantity'),
SelectedOrderUnitNo: this.get('value.SelectedOrderUnit').UnitNo,
LeadTime: this.get('value.LeadTime'),
LeadTimeDeviation: this.get('value.LeadTimeDeviation'),
StockKeepInterest: this.get('value.StockKeepInterest'),
MaxLevel: this.get('value.MaxLevel'),
MinLevel: this.get('value.MinLevel'),
OrderQuantity: this.get('value.OrderQuantity'),
ReorderLevel: this.get('value.ReorderLevel'),
EnableManualSetRAndQ: this.get('value.EnableManualSetRAndQ'),
ForecastError: this.get('value.ForecastError'),
SelectedHistoryProductId: selectedRefHistProd,
};
var dataString = JSON.stringify(data);
$.ajax({
url: '/ProductRowInfoSite/SaveParameters',
data: {
data: dataString,
},
dataType: 'json',
// "jsonp" is required for cross-domain requests; use "json" for same-domain requests
success: function (result) {
// notify the data source that the request succeeded
//options.success(result);
self._store.dispatch({ type: ActionProductInfoWindow.Saving });
self._parent.refreshParentGrids();
},
error: function (result) {
displayAjaxError(result);
},
type: 'POST',
});
let userStore = new UserStore();
let finishSaved = userStore.translatedString('SOLOSupplier.ProductInfoWindows.FinishSaved');
displaySuccess(finishSaved);
productInfoTextGrid.saveChanges();
orderUnitsGrid.saveChanges();
},
recalc: function () {
var validator = $(self._productInfoWindowId).kendoValidator().data('kendoValidator');
var a = validator.validate();
},
products: new kendo.data.DataSource({
type: 'json',
serverFiltering: true,
pageSize: 100,
transport: {
read: function (options) {
$.ajax({
url: '/ProductRowInfoSite/GetProductInventoryList',
data:
{
'inventoryId': self._inventoryId,
'productId': self._productId,
'data': options.data,
},
//"filter": filter
dataType: 'json', // "jsonp" is required for cross-domain requests; use "json" for same-domain requests
success: function (result) {
// notify the data source that the request succeeded
options.success(result.HistProducts);
},
error: function (result) {
// notify the data source that the request failed
options.error(result);
},
type: 'POST',
});
},
parameterMap: function (data, type) {
return kendo.stringify($.extend({ 'text': $(data.filter.filters).get(0).value }, data));
},
},
}),
isEnabled: true,
onValidate: function (e) {
console.log('onValidate');
let maxLevel = this.get('value.MaxLevel');
let minLevel = this.get('value.MinLevel');
let userStore = new UserStore();
let validationErrorMessage = userStore.translatedString('uctrlSupplierWeb.MaxLevelMinLevelWarning');
let validator = $(self._productInfoWindowId).kendoValidator({
messages: {
custom: validationErrorMessage,
},
rules: {
custom: function (input) {
if (input.is('[name=minLevelParameter]') && input.val() === '') {
return true;
} else if (input.is('[name=minLevelParameter]') && input.val() !== '' && maxLevel !== null) {
return maxLevel > minLevel;
}
if (input.is('[name=maxLevelParameter]') && input.val() === '') {
return true;
} else if (input.is('[name=maxLevelParameter]') && input.val() !== '' && minLevel !== null) {
return maxLevel > minLevel;
} else {
return true;
}
},
},
},
).data('kendoValidator');
if (validator.validate() === true) {
self._store.dispatch({ type: ActionProductInfoWindow.Changing });
} else {
self._store.dispatch({ type: ActionProductInfoWindow.Cancelling });
}
},
});
kendo.bind($(self._productInfoWindowId + ' ' + '#tabInventoryControl'), self._productInfoDetailsViewModel);
try {
let result = await self._getMvvmData(self._inventoryId, self._productId, self._supplierId);
self._productInfoDetailsViewModel.products.read();
self._productInfoDetailsViewModel.set('value', result);
if (result.UnitsOnOrderAfterLeadtime === true) {
if ($(self._productInfoWindowId + ' ' + '#valueUnitsOnOrder').data('kendoNumericTextBox')) {
let widget = $(self._productInfoWindowId + ' ' + '#valueUnitsOnOrder').data('kendoNumericTextBox');
widget.wrapper.find('input').addClass('lightRed');
}
}
if ($(self._productInfoWindowId + ' ' + '#minLevelParameterId').data('kendoNumericTextBox')) {
$(self._productInfoWindowId + ' ' + '#minLevelParameterId')
.data('kendoNumericTextBox')
.min(result.MinLevelDefault);
}
if ($(self._productInfoWindowId + ' ' + '#maxLevelParameterId').data('kendoNumericTextBox')) {
$(self._productInfoWindowId + ' ' + '#maxLevelParameterId')
.data('kendoNumericTextBox')
.min(result.MinLevelDefault);
}
var validator = $(self._productInfoWindowId).kendoValidator().data('kendoValidator');
validator.validate();
let element = $(self._productInfoWindowId);
window.kendo.ui.progress(element, false);
} catch ([jqXHR, textStatus, errorThrown]) {
displayAjaxError(jqXHR, textStatus, errorThrown);
productInfoDetailsViewModel.set('value', []);
window.kendo.ui.progress(element, false);
}
}
}
Saving edits in product info modal deletes used filters on products grid
if (productNo === null) {
let newFilter = await self._getFilterOnlyFromLocalStorage();
let totalFilter = $(self._gridId).data("kendoGrid").dataSource.filter();
totalFilter.filters.push.apply(totalFilter.filters, newFilter.filters);
$(self._gridId).data("kendoGrid").dataSource.filter(newFilter);
self._setPredefinedFilterButton(self);
}
}
I have a problem with a specific bootstrap treeview, I have tried everything but the node does not expand, I use ajax request through a load file where I retrieve the information coming from the database, the data appears normally, the only one I have already tried all the methods that the treeview bootstrap provides, but it returns that it does not know the method used, below I will send the specific code that I use.
Function that calls a tree:
var levelTree = 2;
function getTree() {
var data = '';
$.ajax({
url: 'atividades/atividades_load.php',
data: {idObraAtiva: <?php echo $idObra; ?>},
async: false,
dataType: 'json',
type: 'post',
beforeSend: function () {
},
success: function (retorno) {
data = retorno;
console.log(retorno);
},
error: function () {
bootbox.alert('Erro, contate o suporte!');
}
});
return data;
}
$('#atividadeTree').treeview({
data: getTree(),
levels: levelTree,
backColor: "#C4E3F3",
onNodeSelected: function (event, data) {
if (data.qtdfilhos == 0) {
$('#table_Andamento').bootstrapTable('refresh', {url: 'atividades/atividade_andamento_load.php?q=' + data.id});
}
$('#table_AtividadeFilha').bootstrapTable('refresh', {url: 'atividades/atividade_filha_load.php?p=' + data.id});
$('#fmAndamento_idatividade').val(data.id);
$('#fmAtividadeSub_idAtividade').val(data.id);
},
onNodeExpanded: function (event, data) {
$.ajax({
url: 'atividades/atividades_load.php',
data: {idObraAtiva: <?php echo $idObra; ?>,idNo:data.id},
async: false,
dataType: 'JSON',
type: 'POST',
beforeSend: function (){
},
success: function (filho){
$('#atividadeTree').treeview('addNode',[filho, data.id,
{silent: false} ]);
console.log(filho);
},
error: function () {
bootbox.alert('Erro, contate o suporte!');
}
});
}
});
Function that calls the data, and reorganizes the treeview
<?php
include('../../sessao.php');
require_once('../../J3_FrameWork/Conexao.php');
function getItemPai($_arrLista, $_id)
{
foreach ($_arrLista as $item) {
if ($item->id == $_id) {
if (!property_exists($item, 'nodes')) $item->nodes = array();
return $item;
}else
if (property_exists($item, 'nodes')) {
if (is_array($item->nodes)) {
$aux = getItemPai($item->nodes, $_id);
if ($aux != null)
return $aux;
}
}
}
return null;
}
$idObra = $_REQUEST['idObraAtiva'];
if (isset($_REQUEST['idNo'])) {
$idNo = $_REQUEST['idNo'];
}else{
$idNo = -1;
}
$conexao = Proxy::mrObra();
$param = array("_parameters" => array($idObra, $idNo));
$resultado = $conexao->comando('GetAtividadesArvore', json_encode($param));
$resultado = json_decode($resultado);
$lista = $resultado->result[0];
$listanova = array();
foreach ($lista as $item) {
$novoitem = new stdClass();
$novoitem->id = $item->ID;
$novoitem->text = $item->DESCRICAO. ' - ' .$item->QTDFILHOS;
$novoitem->qtdfilhos = $item->QTDFILHOS;
$novoitem->valor = $item->VALOR;
$novoitem->qtdativsub = $item->QTDATIVSUB;
if($item->QTDFILHOS > 0)
{
$novoitem->nodes = array();
}
if ($item->IDPAI == -1) {
array_push($listanova, $novoitem);
} else {
array_push($listanova, $novoitem);
}
}
echo json_encode($listanova);
?>
Função que chama os dados, e reorganiza a treeview
<?php
include('../../sessao.php');
require_once('../../J3_FrameWork/Conexao.php');
function getItemPai($_arrLista, $_id)
{
foreach ($_arrLista as $item) {
if ($item->id == $_id) {
if (!property_exists($item, 'nodes')) $item->nodes = array();
return $item;
}else
if (property_exists($item, 'nodes')) {
if (is_array($item->nodes)) {
$aux = getItemPai($item->nodes, $_id);
if ($aux != null)
return $aux;
}
}
}
return null;
}
$idObra = $_REQUEST['idObraAtiva'];
if (isset($_REQUEST['idNo'])) {
$idNo = $_REQUEST['idNo'];
}else{
$idNo = -1;
}
$conexao = Proxy::mrObra();
$param = array("_parameters" => array($idObra, $idNo));
$resultado = $conexao->comando('GetAtividadesArvore', json_encode($param));
$resultado = json_decode($resultado);
$lista = $resultado->result[0];
$listanova = array();
foreach ($lista as $item) {
$novoitem = new stdClass();
$novoitem->id = $item->ID;
$novoitem->text = $item->DESCRICAO. ' - ' .$item->QTDFILHOS;
$novoitem->qtdfilhos = $item->QTDFILHOS;
$novoitem->valor = $item->VALOR;
$novoitem->qtdativsub = $item->QTDATIVSUB;
if($item->QTDFILHOS > 0)
{
**$novoitem->nodes = array();**
}
if ($item->IDPAI == -1) {
array_push($listanova, $novoitem);
} else {
array_push($listanova, $novoitem);
}
}
echo json_encode($listanova);
?>
I know this has been asked before but I really can't get my head round this. I have tried everything to get rid of this error but it just won't go away. Here is my code and I am given the following error message when generating my chart: All series on a given axis must be of the same data type.
C#
public static object[][] GetBarData()
{
string strSQL = #"SELECT [Expected Month] , ISNULL([0],0) AS [0],
ISNULL([0.10],0) AS [10],
ISNULL([0.25],0) AS [25],
ISNULL([0.50],0) AS [50],
ISNULL([0.75],0) AS [75],
ISNULL([0.90],0) AS [90],
ISNULL([1.00],0) AS [100]
FROM (
SELECT MONTH(D.expected_date) AS [Expected Month], P.probability AS [Category], COUNT(O.id) AS [Customers]
FROM opportunity_probability P
INNER JOIN opportunity_detail D ON D.probability_id = P.id
INNER JOIN opportunities O ON D.opportunity_id = O.id
INNER JOIN (SELECT opportunity_id FROM opportunity_detail GROUP BY opportunity_id) T ON T.opportunity_id = O.customer_id
GROUP BY P.probability, MONTH(D.expected_date)
) ST
PIVOT (
SUM([Customers])
FOR [Category] IN ([0],[0.10],[0.25],[0.50],[0.75],[0.90],[1.00])
) PIV";
DataTable dt = MIDB.DataAccess.LoadDTFromSQL(System.Configuration.ConfigurationManager.ConnectionStrings["MIDB"].ConnectionString, strSQL);
return dtToArray(dt, new Object[9] { "Period", "0%", "10%", "25%", "50%", "75%", "90%", "100%", "Customers" });
}
public static object[][] dtToArray(DataTable dt, Object[] header)
{
Object[][] obj = new Object[dt.Rows.Count + 1][];
obj[0] = header;
int k = header.Length;
for (int i = 0; i < dt.Rows.Count; i++)
{
DataRow row = dt.Rows[i];
obj[i + 1] = new object[k];
for (int j = 0; j < dt.Columns.Count; j++)
{
if (dt.Columns[j].DataType == Type.GetType("System.Decimal"))
{
obj[i + 1][j] = Convert.ToDouble(row[j]);
}
else if (dt.Columns[j].DataType == Type.GetType("System.Int32"))
{
obj[i + 1][j] = Convert.ToInt32(row[j]);
}
else if (dt.Columns[j].DataType == Type.GetType("System.DateTime"))
{
obj[i + 1][j] = GenericMethods.jsMilliseconds(Convert.ToDateTime(row[j]));
}
else
{
obj[i + 1][j] = row[j].ToString();
}
}
}
return obj;
}
google.load("visualization", "1.1", {
packages: ["bar", "corechart"]
});
ASPX Page
$(document).ready(function () {
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: 'PipelineChart.aspx/GetChartData',
success:
function (response) {
genCharts(response.d);
}
});
})
$(window).resize(function () {
getDataPost();
});
function getDataPost() {
$(document).ready(function () {
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'application/json',
url: 'PipelineChart.aspx/GetChartData',
success:
function (response) {
genCharts(response.d);
}
});
})
}
function genCharts(obj) {
drawBar(obj[0]);
}
function drawBar(obj) {
var data = google.visualization.arrayToDataTable(obj);
var options = {
width: '100%',
height: '600',
isStacked: true
}
var chart = new google.visualization.BarChart(document.getElementById('Bar'));
chart.draw(data, options)
}
google.setOnLoadCallback(drawBar);
I have an $.ajax function on my page to populate a facility dropdownlist based on a service type selection. If I change my service type selection back and forth between two options, randomly the values in the facility dropdownlist will remain the same and not change. Is there a way to prevent this? Am I doing something wrong?
Javascript
function hydrateFacilityDropDownList() {
var hiddenserviceTypeID = document.getElementById('<%=serviceTypeID.ClientID%>');
var clientContractID = document.getElementById('<%=clientContractID.ClientID%>').value;
var serviceDate = document.getElementById('<%=selectedServiceDate.ClientID%>').value;
var tableName = "resultTable";
$.ajax({
type: 'POST',
beforeSend: function () {
},
url: '<%= ResolveUrl("AddEditService.aspx/HydrateFacilityDropDownList") %>',
data: JSON.stringify({ serviceTypeID: TryParseInt(hiddenserviceTypeID.value, 0), clientContractID: TryParseInt(clientContractID, 0), serviceDate: serviceDate, tableName: tableName }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
a(data);
}
,error: function () {
alert('HydrateFacilityDropDownList error');
}
, complete: function () {
}
});
}
function a(data) {
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
var tableName = "resultTable";
if (facilityDropDownList.value != "") {
selectedFacilityID = facilityDropDownList.value;
}
$(facilityDropDownList).empty();
$(facilityDropDownList).prepend($('<option />', { value: "", text: "", selected: "selected" }));
$(data.d).find(tableName).each(function () {
var OptionValue = $(this).find('OptionValue').text();
var OptionText = $(this).find('OptionText').text();
var option = $("<option>" + OptionText + "</option>");
option.attr("value", OptionValue);
$(facilityDropDownList).append(option);
});
if ($(facilityDropDownList)[0].options.length > 1) {
if ($(facilityDropDownList)[0].options[1].text == "In Home") {
$(facilityDropDownList)[0].selectedIndex = 1;
}
}
if (TryParseInt(selectedFacilityID, 0) > 0) {
$(facilityDropDownList)[0].value = selectedFacilityID;
}
facilityDropDownList_OnChange();
}
Code Behind
[WebMethod]
public static string HydrateFacilityDropDownList(int serviceTypeID, int clientContractID, DateTime serviceDate, string tableName)
{
List<PackageAndServiceItemContent> svcItems = ServiceItemContents;
List<Facility> facilities = Facility.GetAllFacilities().ToList();
if (svcItems != null)
{
// Filter results
if (svcItems.Any(si => si.RequireFacilitySelection))
{
facilities = facilities.Where(f => f.FacilityTypeID > 0).ToList();
}
else
{
facilities = facilities.Where(f => f.FacilityTypeID == 0).ToList();
}
if (serviceTypeID == 0)
{
facilities.Clear();
}
}
return ConvertToXMLForDropDownList(tableName, facilities);
}
public static string ConvertToXMLForDropDownList<T>(string tableName, T genList)
{
// Create dummy table
DataTable dt = new DataTable(tableName);
dt.Columns.Add("OptionValue");
dt.Columns.Add("OptionText");
// Hydrate dummy table with filtered results
if (genList is List<Facility>)
{
foreach (Facility facility in genList as List<Facility>)
{
dt.Rows.Add(Convert.ToString(facility.ID), facility.FacilityName);
}
}
if (genList is List<EmployeeIDAndName>)
{
foreach (EmployeeIDAndName employeeIdAndName in genList as List<EmployeeIDAndName>)
{
dt.Rows.Add(Convert.ToString(employeeIdAndName.EmployeeID), employeeIdAndName.EmployeeName);
}
}
// Convert results to string to be parsed in jquery
string result;
using (StringWriter sw = new StringWriter())
{
dt.WriteXml(sw);
result = sw.ToString();
}
return result;
}
$get return XHR object not the return value of the success call and $get function isn't synchronous so you should wait for success and check data returned from the call
these two lines do something different than what you expect
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
change to something similar to this
var facilityDropDownList;
$.ajax({
url: '<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>',
type: 'get',
dataType: 'html',
async: false,
success: function(data) {
facilityDropDownList= data;
}
});
The initial function looks like this:
function addressTypeaheadInitialize() {
$('.address').typeahead().on('keyup', function(ev) {
ev.stopPropagation();
ev.preventDefault();
if ($.inArray(ev.keyCode, [ 40, 38, 9, 13, 27 ]) != -1) {
return;
}
var self = $(this);
self.data('typeahead').source = [];
if (!self.data('active') && self.val().length > 0) {
self.data('active', true);
self.addClass('hint-loading');
$.ajax({
type : 'post',
url : '/jetty/typeahead_address',
data : {
query : this.value
}, /*
* ie {'TYPE':$ (this).attr('data-input-type'),
* 'VAR2','test2'}
*/
dataType : 'json',
cache : false,
success : function(data) {
self.data('active', true);
var source = [], highlights = [], i = data.source.length;
while (i--) {
source[i] = data.source[i];
highlights[i] = data.highlights[i];
}
self.data('typeahead').highlighter = function(item) {
var id = source.indexOf(item);
return highlights[id];
};
self.data('typeahead').source = source;
self.trigger('keyup');
self.data('active', false);
self.removeClass('hint-loading');
},
error : function(jqXHR, textStatus, errorThrown) {
self.removeClass('hint-loading');
}
});
self.data('active', false);
}
});
}
I tried to make it work on new typeahead this way:
function addressTypeaheadInitialize() {
var suggestions = function(query, cb) {
$.ajax({
type : 'post',
url : '/jetty/typeahead_address',
data : {
query : query
},
dataType : 'json',
cache : false,
success : function(data) {
console.log(data);
var source = [], highlights = [], i = data.source.length;
while (i--) {
source[i] = data.source[i];
highlights[i] = data.highlights[i];
}
cb(source);
},
error : function(jqXHR, textStatus, errorThrown) {
}
});
}
var options = {
highlighter : function(item) {
var id = source.indexOf(item)
return highlights[id];
},
source: suggestions,
}
$('.address').typeahead(null, options);
}
Now I can't even input any text in the form! What am I doing wrong?