Choose different Template at Run Time with InstantSearch.js - javascript

I want to be able to change the template depending on the value I got retrieved from the search. I thought of changing the variable content like this:
search.addWidget(
instantsearch.widgets.hits({
container: '#hits',
hitsPerPage: 12,
templates: {
empty: noResultsTemplate,
item: hitTemplate
},
transformData: function (hit) {
if (hit.myVariable == true) {
this.templates.item = otherTemplateVariable;
}
return hit;
}
})
);
But I get an error: 'Unable to get property 'templates' of undefined or null reference'

The problem seems to be that you are referencing this and that points to the function transformData which do not have the templates attribute, try to extract your object to access it :
var data = {
container: '#hits',
hitsPerPage: 12,
templates: {
empty: noResultsTemplate,
item: hitTemplate
},
transformData: function (hit) {
if (hit.myVariable == true) {
//access the templates attribute
data.templates.item = otherTemplateVariable;
}
return hit;
}
};
search.addWidget(
instantsearch.widgets.hits(data)
);

Related

ag-grid: Using Javascript, find the row id for a given data

I have a list of employees and I want to find the “id” of the row where firstName=Bob which is unique. In other words, I know the firstName supplied as “Bob” and now, I just need to find the row id using Javascript for ag-grid.
According to the documentation https://www.ag-grid.com/javascript-grid/accessing-data/ and I see that the rowNode can be got by using
getRowNodeId: data => data.id,
But I am just unable to to send the parameters (Bob), so that ag-grid finds and puts the id in some assigned variable. I think foreachloop is unnecessary to iterate each and every row, in case if the dataset is too big, then it will be an overhead.
I have the index.html file and a cellRenderer script as shown below. When the circle icon is clicked, I get the row Id correctly, but I am unable to retrieve the firstName, lastName etc.
I tried in two ways (i) writing the evenlistener inside the cellRenderer class, but most convenient for is to take this event listener as a function out of the cell Renderer file. (ii) So, I added a function called getAlert() which you can see as commented. Nothing works for me.
index.html
<div id="myGrid" style="height: 800px; width:100%;" class="ag-theme-alpine"></div>
<script>
var colSpan = function (params) {
return params.data === 2 ? 3 : 1;
};
const columnDefs = [
{ headerName:'FIRST NAME',field: "firstName", width:100, cellClass: 'my-class', colSpan: colSpan,},
{ headerName:'LAST NAME',field: "lastName", cellClass: 'my-class', flex: 6,},
{ headerName:'DESIGNATION (%)',field: "designation", cellClass: 'my-class', flex: 1,},
{ headerName:'INFO', field: "row_id",flex: 2, cellRenderer: 'infoCellRenderer'},
{ headerName:'COMMAND',field: "action",flex: 2,},
];
// let the grid know which columns and what data to use
const gridOptions = {
defaultColDef: {
resizable: true,
},
columnDefs: columnDefs,
getRowNodeId: data => data.id,
onGridReady: event => console.log('The grid is now ready'),
components:{
infoCellRenderer: InfoCellRenderer,
},
};
/*function getAlert(params)
{
console.log(params.node.firstName+","+params.firstName+","+params.value);
}*/
document.addEventListener('DOMContentLoaded', function () {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
//gridOptions.api.refreshView();
agGrid
.simpleHttpRequest({
url: 'XXXXXXX',
})
.then((data) => {
gridOptions.api.setRowData(data);
});
});
</script>
cellRenderer class
class InfoCellRenderer {
constructor() {}
// gets called once before the renderer is used
init(params) {
// create the cell
this.eGui = document.createElement('div');
this.eGui.innerHTML = '<i class="fas fa-info-circle"></i>';
// get references to the elements we want
this.circleValue = this.eGui.querySelector('.circle');
// add event listener to button
this.cellValue = this.getValueToDisplay(params);
//this.eventListener = () => getAlert('${params}');
this.eventListener = () => console.log(`${params.node.id},${params.node.firstName},${params.node.row_id}`);
this.circleValue.addEventListener('click', this.eventListener);
}
getGui() {
return this.eGui;
}
// gets called whenever the cell refreshes
refresh() {
// set value into cell again
this.cellValue = this.getValueToDisplay(params);
//this.eValue.innerHTML = this.cellValue;
// return true to tell the grid we refreshed successfully
return true;
}
// gets called when the cell is removed from the grid
destroy() {
// do cleanup, remove event listener from button
if(this.circleValue) {
// check that the button element exists as destroy() can be called before getGui()
this.circleValue.removeEventListener('click', this.eventListener);
}
}
getValueToDisplay(params) {
return params.valueFormatted ? params.valueFormatted : params.value;
}
}
if firstName is unique you can do as followed:
this.gridOptions.getRowNodeId = data => {
return data.firstName;
};
this code tells ag-grid to use firstName as its internal row Id. so you can easily get the row by:
const node = this.gridApi.getRowNode('Bob');
see link (note // ********* comments ) for full example
gridOptions.api.getModel().forEachNode(
function(rowNode, index){
if (rowNode.data.firstName == "Bob") {
row_index = index;
row = gridOptions.api.getModel().rowsToDisplay[row_index];
data_dict = row.data;
// do something with your row data, data_dict
}
}
);

how to solve Trying to get property 'bids' of non-object error

I want to display data from bid table in a form of datatable. But I get this error
"Trying to get property 'bids' of non-object" if it doesn't have bids.The bids model is connected to auction model and the auction model is connected to media site model. How to make it display blank record if it doesn't have data.
Here is my controller:
<?php
namespace App\Http\Controllers;
use App\Auction;
use App\Bid;
use App\User;
use App\Media;
use App\MediaSite;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class MediaSiteController extends Controller
{
public function show(MediaSite $mediaSite)
{
$auction = $mediaSite->auction;
$bids = $auction->bids;
return view('admin.media-site.show', ['mediaSite' => $mediaSite,'auction' => $auction], compact('auction'));
}
My view:
<body>
<div id="datatable-bid"></div>
</body>
<script>
$(document).ready(function () {
var datatableBid = $('#datatable-bid').mDatatable({
// datasource definition
data: {
type: 'local',
source: {!! json_encode($auction->bids) !!},
pageSize: 10
},
// layout definition
layout: {
theme: 'default', // datatable theme
class: '', // custom wrapper class
scroll: false,
footer: false // display/hide footer
},
// column sorting
sortable: true,
pagination: true,
search: {
input: $('#panel-search')
},
// columns definition
columns: [
{
field: "price",
title: "Price",
}, {
field: "month",
title: "Month",
},{
field: "user_id",
title: "User Id",
}
]
});
</script>
Here is my error:
Trying to get property 'bids' of non-object
place following after $auction = $mediaSite->auction;
if($auction){
$bids = $auction->bids;
}else{
//put following line or whatever you need to do if there is no data comes
$auction = [];
}
In the show() function make these changes
$auction = $mediaSite->auction;
if($auction) {
$bids = $auction->bids;
} else {
$bids = [];
}
// now send $bids to view along with $auction
// may be like this
// return view(..., compact($auction, $bids));
Then, in your view make this change
// datasource definition
data: {
type: 'local',
source: {!! json_encode($bids) !!},
pageSize: 10
},
See if this helps.

ExtJS 5: Initial ViewModel data not firing formula

I have a ViewModel that contains some initial data... this initial data is based off of a global variable that I have created. In the ViewModel, I have a formula that does some logic based on the data set from the global variable. The interesting thing is, this formula does not fire when the ViewModel is created. I'm assuming this is because the Something.Test property does not exist, so the ViewModel internals have some smarts to not fire the method if that property does not exist.
If the property doesn't exist, how do I fire the formula anyway? I know I could look for Something check to see if it has the property Test, but I'm curious why this example wouldn't work. Here's the example:
Ext.application({
name : 'Fiddle',
launch : function() {
// Define global var Something
Ext.define('Something', {
singleton: true
});
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myView',
data: {
Something: window.Something
},
formulas: {
testSomething: function(getter) {
console.log('here', getter('Something.Test'));
return getter('Something.Test');
},
myTitle: function(getter) {
return 'My Title';
}
}
});
Ext.define('MyView', {
extend: 'Ext.panel.Panel',
bind: {
title: '{myTitle}'
},
viewModel: {
type: 'myView'
}
});
var view = Ext.create('MyView', {
renderTo: Ext.getBody()
});
// This will fire the ViewModel formula
//view.getViewModel().set('Something', window.Something);
console.log(Something, window.Something)
}
});
You can workout some logic to handle when Something.Test is not available, something like:
data: {
Something: window.Something && window.Something.Test || {Test: null}
},
formulas: {
testSomething: function(get) {
var val = get('Something.Test');
console.log('Test');
return val;
},
myTitle: function(getter) {
return 'My Title';
}
}

jQuery ui autocomplete usin JSON file

I am having some trouble getting autocomplete to work specifically with a json file. It
giving following error whenever something is entered in the text box
url is undefined
following is my jQuery code
$(document).ready(function() {
$('#autocomplete').autocomplete({
minChars: 1,
source: function(request, response) {
var url='dataa.json';
$.getJSON(url,{term: request.term},function(data){
response($.map(data.ledgers, function(item) {
return item.value;
}));
})
}
});
});
and the JSON
{
"ledgers":
[
{
"id":"2001",
"name":"Bharat"
},
{
"id":"2003",
"name":"Gaurav"
},
{
"id":"2002",
"name":"Pankaj"
},
{
"id":"2022",
"name":"Purchase"
},
{
"id":"2007",
"name":"Ram"
},
{
"id":"2008",
"name":"Ramesh"
},
{
"id":"2009",
"name":"Suresh"
}
]}
Your JSON file format needs to contain value or label (or both). Change name to value and it should work fine.
$('#autocomplete').autocomplete({
minChars: 1,
source: function(request, response) {
var url='dataa.json';
$.getJSON(url,{term: request.term},function(data){
response($.map(data.ledgers, function (value, key) {
return {
label: value,
value: key
};
}));
})
}
});
Try adding 'use strict'; at the top of your $(document).ready(). That may point out what the problem is...
return item.value;
item does not have a value, try returning id or name, which it does have.

Why is the button in my ExtJS grid appearing as "[object Object]"?

In an ExtJS grid I have a column in which when the content of a cell is a certain value, a button should be displayed.
I define the column which will contain the button like this, which calls a rendering function:
{
header: 'Payment Type',
width: 120,
sortable: true,
renderer: renderPaymentType,
dataIndex: 'paymentType'
}]
in the rendering function, I return either text or the button itself:
function renderPaymentType(val) {
if(val!='creditInform') {
return val;
} else {
return new Ext.Button({
text: val,
width: 50,
handler: function() {
alert('pressed');
}
});
}
}
This basically works, except that the button is displayed as the text [object Object]:
What do I have to do so that the button is displayed as a button instead of as text?
Addendum
adding .getEl():
function renderPaymentType(val) {
if(val!='creditInform') {
return val;
} else {
return new Ext.Button({
text: val,
width: 50,
handler: function() {
alert('pressed');
}
}).getEl();
}
}
produces a blank:
adding .getEl().parentNode.innerHTML:
function renderPaymentType(val) {
if(val!='creditInform') {
return val;
} else {
return new Ext.Button({
text: val,
width: 50,
handler: function() {
alert('pressed');
}
}).getEl().parentNode.innerHTML;
}
}
causes some kind of rendering problem with the rest of the code altough in Firebug I strangely don't get any errors:
Try
return new Ext.Button({
text: val,
width: 50,
handler: function() {
alert('pressed');
}
}).getEl();
Your returning a JavaScript object to your renderer rather then a dom node. If doesn't work then your renderer expects a HTML string so you can try
Ext.Button({ ... }).getEl().parentNode.innerHTML
Either should solve your problem.
This worked for me:
renderer: function (v, m, r) {
var id = Ext.id();
Ext.defer(function () {
Ext.widget('button', {
renderTo: id,
text: 'Edit: ' + r.get('name'),
width: 75,
handler: function () { Ext.Msg.alert('Info', r.get('name')) }
});
}, 50);
console.log(Ext.String.format('<div id="{0}"></div>', id));
return Ext.String.format('<div id="{0}"></div>', id);
}
Ref: http://ext4all.com/post/how-add-dynamic-button-in-grid-panel-column-using-renderer
When ever you see syntax of that nature, chances are you're looking at the output of the toString method on an object.
Which means you're displaying the object, and not a result.
console.log({
toString:function(){
return 'toString method.'
};
});
console.log(new Object())
Object.prototype.toString = function(){
return 'All object to string methods are now overriden.';
}
console.log(new Object());
the API documentation says this
renderer : Mixed For an alternative to
specifying a renderer see xtype
Optional. A renderer is an
'interceptor' method which can be used
transform data (value, appearance,
etc.) before it is rendered). This may
be specified in either of three ways:
A renderer function used to return
HTML markup for a cell given the
cell's data value.
A string which
references a property name of the
Ext.util.Format class which provides a
renderer function.
An object
specifying both the renderer function,
and its execution scope (this
reference) e.g.:
{
fn: this.gridRenderer,
scope: this
}
You're using the renderer function option, which means your function needs to return a html markup string, rather than a new Button object. To show a button, you might need to use the column's editor property

Categories

Resources