jQuery Autocomplete - Show Data Based on Selection - jquery-autocomplete

I have a standard jQuery autocomplete setup similar to the below:
$("input#autocomplete").autocomplete({
source: source,
minLength: 5 ,
select: function( event, ui ) {
alert(ui.item.value);
}
});
What I would like is, when the value is chosen, a data-table within the page appears and get populated with data from a database using the value as a search parameter.
So for instance if I select "RED", the table would then show and display data from a query such as SELECT * FROM TABLE WHERE COLUMN='RED'
The query is simplified but can anyone please point me in the right direction?

For this purpose you should request a kind of search page which will act as JSON endpoint for e.g.
$("input#autocomplete").autocomplete({
source: source,
minLength: 5 ,
select: function( event, ui ) {
var _value = ui.item.value;
$.post('services/populate_table.php', // endpoint URL
{ someParameterToTransmit: _value }, // some data to transmit
function(data) { // on complete handler
$('.result').html(data); // populate retrieved data in any form you need
} // on complete function
); // post
} // on select (autocomplete)
}); // autocomplete
Data from endpoint also can be retrieved as JSON.
You can read documentation for more information about request method.

If I understand you correctly, you're looking for $.post.
For example, your jQuery would be:
$("input#autocomplete").autocomplete({
source: source,
minLength: 5 ,
select: function( event, ui ) {
$.post("autocomplete.php", { option: ui.item.value }, function(data){
$("table").html( data[0] );
// sets the content of a table element to the first matched row
});
}
});
And in autocomplete.php, you would have something like this:
// DB connect
// use $_POST['option'] here for the selected option
$sth = mysql_query("SELECT ...");
$r = mysql_fetch_assoc($sth);
print $r;
What we do here is request the page autocomplete.php and POST the data, which in this case is the selected value. autocomplete.php grabs that POSTed value and searches the database (you can customize that query to fit your needs). The page then prints an array of the matched rows, which is the data received by the jQuery, and can be traversed as a Javascript array.

Related

How to get Tabulator to populate a headerFilter ONLY when it is clicked

I'm using Tabulator with ajax to pull paginated data to the table. I'd like to use headerFilters with valuesURL but the AJAX request is a POST not a GET and valuesURL only works with GET. He alternative is to use values, but that seems to want to pull the values each time the data is refreshed. I need the headerFilter options to be refreshed ONLY when it the input box is clicked. Psuedo-process below...
Load all data
user clicks one headerFilter "City"
ajax called via POST to get list of relevant values for "City"
headerFilter is populated with list, which is then presented to the user via the drop down
Is this possible?
I've tried using a function in headerFilterParams to get the values but each headerFilter is refreshed when the data is refreshed as opposed to just the one that was clicked.
You can use the headerFilter in combination with a custom header filter component that makes the AJAX call to get the values when the header filter is clicked.
Example:
var cityFilter = function(headerValue, rowValue, rowData, filterParams){
// code to filter data based on selected city
};
// Custom header filter component
var customCityFilter = function(header) {
var self = this;
self.element = document.createElement("input");
self.element.setAttribute("type", "text");
self.element.setAttribute("placeholder", "Type to filter");
// Add click event to make the AJAX call when the input box is clicked
self.element.addEventListener("click", function() {
// Make the AJAX call to get the list of relevant values for "City"
// Replace with your own AJAX code
// Example using jQuery
$.ajax({
type: "POST",
url: "your_url",
data: {},
success: function(data) {
// Populate the headerFilter with the list of values
header.setFilterValues(data);
}
});
});
// Return the custom filter component
return self.element;
};
// Initialize the table with the custom header filter
var table = new Tabulator("#example-table", {
columns:[
{title:"City", field:"city", headerFilter:"custom", headerFilterParams:{component:customCityFilter}, headerFilterFunc:cityFilter},
// other columns
],
});

React-Bootstrap-Table-Next Only One Row of Data in Table

I am trying to create a table for my website and for some reason it is only showing the first row of data.
This is how I am formatting the columns of the data:
const { items } = this.props.item;
// console.log({ items });
// react - bootstrap - table - next
const columns = [{
dataField: 'team',
text: 'Team',
sort: true,
formatter: (cellContent, row, rowIndex) => (
Object.values(row.team)[rowIndex]
)
}, {
dataField: 'current_Rank',
text: 'Current Rank',
sort: true,
formatter: (cellContent, row, rowIndex) => (
Object.values(row.current_Rank)[rowIndex]
)
}, {
dataField: 'new_Rank',
text: '321 Rank',
sort: true,
formatter: (cellContent, row, rowIndex) => (
Object.values(row.new_Rank)[rowIndex]
)
}];
This is how I am returning the table so that it renders the table:
return (
<BootstrapTable
keyField="team"
data={items}
columns={columns}
striped
hover />
)
}
}
The data:
Picture from the console
Live site: https://nhl-321-pointsystem.herokuapp.com/
I looked up your network response for /api/items API call, and found out that the data contains only one item. This being one of the reason you're seeing a single row when the table is rendered.
Please note the, another reason for the issue is, react-bootstrap-table-next key
data accepts a single Array object. And not array of single object.
You should re-arrange your data so that key 'team' will be present for all items in the array. And rest of the column header values (e.g. current_Rank) are available for each like.
Something like a reformat function I created in the sandbox available here.
Plus point - After you apply the reformat function, you won't need formatter for each column unlike your previous solution.
Alternate but recommended solution would be to send the formatted response from the API endpoint only, instead of re-parsing and creating new object to fit the needs of UI.
Sandbox link - https://codesandbox.io/embed/32vl4x4oj6

SuiteScript 2.0 Transaction Saved Search Filter

I have created a saved search for transaction in netsuite and with suitescript 2.0 I am showing saved search data in my application. In application user can apply filter on any fields (please see the attached screenshot). For example user select "Aug 2011" for posting period, only transactions of Aug 2011 should be loaded. This works fine if I create a filter with internalid of "Aug 2011", but on UI I dont have internal id.
sample code:
/*
here is my required module
*/
function getTransactionData(datain)
{
try
{
var objSearch = search.load
({
id: datain.savedsearchid
});
/***** Work *****/
objSearch.filters.push(search.createFilter({ name: "postingperiod", operator: "ANYOF", values: "1" })); //here 1 is internalid of periodname "Aug 2011"
/***** Not Work (SSS_INVALID_SRCH_FILTER_JOIN) *****/
//objSearch.filters.push(search.createFilter({ name: "postingperiod", join: "accountingperiod", operator: "ANYOF", values: "Aug 2011" }));
objSearch.run();
}
catch(ex)
{
log.error("getTransactionData", ex);
throw ex;
}
}
I tried with join but seeing "SSS_INVALID_SRCH_FILTER_JOIN" error from Netsuite.
Can any one please help me regarding this.
Thanks in advance
I edited your code to a more simplified one to understand better.
If you get the gist of how it works, you can edit/customize the way you want.
I assume there is join 'accountingperiod' option available for 'postingperiod' and this works perfectly in your saved search you created in netsuite without using suitescript.
/*
here is my required module
*/
function getTransactionData(datain) {
try {
var objSearch = search.load({
id: datain.savedsearchid
});
var defaultFilters = objSearch.filters;
var customFilters = [];
//Adding filter
customFilters = ['postingperiod', 'ANYOF', '1'];
defaultFilters.push(customFilters);
customFilters = undefined;
customFilters = [];
//Adding filter
/*
customFilters = ['postingperiod.accountingperiod', 'ANYOF', 'Aug 2011'];
defaultFilters.push(customFilters);
*/
objSearch.filters = defaultFilters;
var objSearch_run = objSearch.run().getRange({
start: 0,
end: 10
});
} catch (ex) {
log.error("getTransactionData", ex);
throw ex;
}
}
If you want to know how filters is stored in saved search you created in netsuite, you can use the script debugger.
The following code is suitescript 1.0
//Load Saved Search
get();
function get() {
var search = nlapiLoadSearch('transaction', ' ENTER SAVED SEARCH ID HERE ');
log.debug('search',search);
var searchFilters = search.getFilterExpression();
log.debug('searchFilters',searchFilters);
return search;
}
I assume your application is a Suitelet? If so, you need to do a select field type of your record. So probably of 'posting periods'. This will show your periods in a drop down.
When the user selects it, have a client side script auto refresh the data and load your saved search.
Alternatively, you can load all the data and do the filtering client side DOM filtering. Really need a bit more information about your "application".

How to split mongodb query into result pages

I have learning application that only create users, manage sessions and delete users. The backend is in Node.js.
I have the query that retrieve the list of users
var userList = function ( page, callback ) {
user.find({}, function ( err, doc ) {
if (err) {
callback (err);
}
callback ( doc );
});
};
then I have the handler that send it back to the application
var userList = function ( req, res ) {
var page = req.param.page;
models.account.userList( page, function ( result ) {
res.json ( 200, result );
});
};
and on the client side I take the results and display them in a table on the browser.
What I want to accomplish, is to split the list into pages of... lets say... 10 users each. So using the parameter Page of the function userList I would expect to send the right answers:
Page1: results 0 to 9
page2: results 10 to 19
etc
I could do a loop to extract what I want, but I am sure that receive from the query the whole list of users to reprocess it on a loop to only extract 10 users is not the right approach, but I could not figure out what the right approach would be.
I have already googled, but did not find the answer what I wanted. Also quickly check MongoDB documentation.
As you can guess I am new at this.
Can you please help me guiding on the right approach for this simple task?
Thank you very much.
Using bduran code, I was able to do the pagination that I wanted. The code after the answer is:
var userList = function ( page, itemsPerPage, callback ) {
user
.find()
.skip( (page - 1) * itemsPerPage )
.limit ( itemsPerPage )
.exec ( function ( err, doc ) {
if (err) {
//do something if err;
}
callback ( doc );
});
};
The most easy and direct way to do this is with skip and query. You select pages of, for example, ten elements and then skip ten times that number per page. With this method you don't need to get all elements and if the query is sorted with and index is really fast:
user
.find()
.skip((page-1)*10)
.limit(10)
.exec(function(err, doc){
/*Rest of the logic here*/
});
If you need to sort the results in a non-natural order (with .sort) you will need to create an index in the database to speed up and optimize the queries. You can do it with .ensureIndex. In the terminal put the query you use to do and you are done.
db.user.ensureIndex({ createdAt: -1 })

Fetch Backbone collection with search parameters

I'd like to implement a search page using Backbone.js. The search parameters are taken from a simple form, and the server knows to parse the query parameters and return a json array of the results. My model looks like this, more or less:
App.Models.SearchResult = Backbone.Model.extend({
urlRoot: '/search'
});
App.Collections.SearchResults = Backbone.Collection.extend({
model: App.Models.SearchResult
});
var results = new App.Collections.SearchResults();
I'd like that every time I perform results.fetch(), the contents of the search form will also be serialized with the GET request. Is there a simple way to add this, or am I doing it the wrong way and should probably be handcoding the request and creating the collection from the returned results:
$.getJSON('/search', { /* search params */ }, function(resp){
// resp is a list of JSON data [ { id: .., name: .. }, { id: .., name: .. }, .... ]
var results = new App.Collections.SearchResults(resp);
// update views, etc.
});
Thoughts?
Backbone.js fetch with parameters answers most of your questions, but I put some here as well.
Add the data parameter to your fetch call, example:
var search_params = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3',
...
'keyN': 'valueN',
};
App.Collections.SearchResults.fetch({data: $.param(search_params)});
Now your call url has added parameters which you can parse on the server side.
Attention: code simplified and not tested
I think you should split the functionality:
The Search Model
It is a proper resource in your server side. The only action allowed is CREATE.
var Search = Backbone.Model.extend({
url: "/search",
initialize: function(){
this.results = new Results( this.get( "results" ) );
this.trigger( "search:ready", this );
}
});
The Results Collection
It is just in charge of collecting the list of Result models
var Results = Backbone.Collection.extend({
model: Result
});
The Search Form
You see that this View is making the intelligent job, listening to the form.submit, creating a new Search object and sending it to the server to be created. This created mission doesn't mean the Search has to be stored in database, this is the normal creation behavior, but it does not always need to be this way. In our case create a Search means to search the DB looking for the concrete registers.
var SearchView = Backbone.View.extend({
events: {
"submit form" : "createSearch"
},
createSearch: function(){
// You can use things like this
// http://stackoverflow.com/questions/1184624/convert-form-data-to-js-object-with-jquery
// to authomat this process
var search = new Search({
field_1: this.$el.find( "input.field_1" ).val(),
field_2: this.$el.find( "input.field_2" ).val(),
});
// You can listen to the "search:ready" event
search.on( "search:ready", this.renderResults, this )
// this is when a POST request is sent to the server
// to the URL `/search` with all the search information packaged
search.save();
},
renderResults: function( search ){
// use search.results to render the results on your own way
}
});
I think this kind of solution is very clean, elegant, intuitive and very extensible.
Found a very simple solution - override the url() function in the collection:
App.Collections.SearchResults = Backbone.Collection.extend({
urlRoot: '/search',
url: function() {
// send the url along with the serialized query params
return this.urlRoot + "?" + $("#search-form").formSerialize();
}
});
Hopefully this doesn't horrify anyone who has a bit more Backbone / Javascript skills than myself.
It seems the current version of Backbone (or maybe jQuery) automatically stringifies the data value, so there is no need to call $.param anymore.
The following lines produce the same result:
collection.fetch({data: {filter:'abc', page:1}});
collection.fetch({data: $.param({filter:'abc', page:1})});
The querystring will be filter=abc&page=1.
EDIT: This should have been a comment, rather than answer.

Resources