select2 optgroup ajax json fomat - json

i want to group returned json data by libelle i end up with the following
script :
$('.membre').select2({
placeholder: 'Select an item',
ajax: {
url: '/select2-autocomplete-ajax',
dataType: 'json',
delay: 250,
data: function (params) {
return {
membre_id: params.term // search term
};
},
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.libelle,
children: [{
id: item.id,
text: item.nom +' '+ item.prenom
}]
}
})
};
},
cache: true
}
});
Output :
is there any possibility to make the group work properly without repeating the libelle ?
JSON output :
[{"id":1,"libelle":"Laboratoire Arithm\u00e9tique calcul Scientifique et Applications","nom":"jhon","prenom":"M"},{"id":2,"libelle":"Laboratoire Arithm\u00e9tique calcul Scientifique et Applications","nom":"JHON","prenom":"jhon"}]

Seems you're looking for something like this https://select2.org/data-sources/formats#grouped-data
// Add this somewhere before the ajax
var groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
processResults: function (data) {
return {
results: $.map(data, function (item,key) {
var children = [];
for(var k in item){
var childItem = item[k];
childItem.text = item[k].nom +' '+ item[k].prenom;
children.push(childItem);
}
return {
text: key,
children: children,
}
})
};

Related

how to deal with datatable-ajax cannot be displayed using server-side

i am trying to display data on my database in laravel using datatable-ajax with server-side but the data i fetched is not displayed in the table
I've tried the json data on the url and it works but it can't appear on datatable-ajax
json
this is the script i'm trying to build using ajax
`
function getData(first_reload) {
var id = <?= $customer->id ?>;
/** Remove */
if ($.fn.DataTable.isDataTable('#datatable-ajax')) {
$('#datatable-ajax').DataTable().destroy();
}
$('#datatable-ajax tbody').empty();
$('#datatable-ajax tfoot th').each(function(index, value) {
var title = $(this).text();
if (index != 0) // id and action
$(this).html('<input type="text" placeholder="Search ' + title + '" />');
});
var table = $('#datatable-ajax').DataTable({
processing: true,
serverSide: true,
ajax: `{{ url('/') }}/customer/show-datatable/${id}`,
order: [
[3, "desc"]
], //or asc
columns: [{
data: 'id',
name: 'id'
},
{
data: 'no_resi',
name: 'no_resi'
},
{
data: 'total_fee',
name: 'total_fee'
},
{
data: 'date',
name: 'date'
},
{
data: 'bayar',
render: function(data, type, row) {
var paid = false;
$.each(row.statuses, function(key, val) {
if (val.id == 5)
paid = true;
});
if (paid) {
return '<span class="text-success">Sudah</span>';
} else {
return '<span class="text-danger">Belum</span>';
// <i class="la la-check"></i>
}
}
},
{
data: 'sampai',
render: function(data, type, row) {
var paid = false;
$.each(row.statuses, function(key, val) {
if (val.id == 4)
paid = true;
});
if (paid) {
return '<span class="text-success">Sudah</span>';
} else {
return '<span class="text-danger">Belum</span>';
// <i class="la la-check"></i>
}
}
},
{
data: 'ambil',
render: function(data, type, row) {
var paid = false;
$.each(row.statuses, function(key, val) {
if (val.id == 7)
paid = true;
});
if (paid) {
return '<span class="text-success">Sudah</span>';
} else {
return '<span class="text-danger">Belum</span>';
// <i class="la la-check"></i>
}
}
},
],
fixedHeader: true,
scrollX: true,
initComplete: function() {
// Apply the search
this.api().columns().every(function() {
var that = this;
$('input', this.footer()).on('keyup change clear', function() {
if (that.search() !== this.value) {
that
.search(this.value)
.draw();
}
});
});
}
});
}
`
this is a view of my problematic table
page

How to fix '415 unsupported media error' on ajax post to controller

The instant the post to the controller happens, the screen show the 415 error...so I am thinking that even though the data goes through somehow my json structure must not be correct.
View Ajax:
function SubAll() {
var selectedValues =
$('#timesheet').DataTable().column(0).checkboxes.selected().toArray();
var instructions = []; //create array of objects
for (var i = 0; i < selectedValues.length; i++) {
instructions.push({ TimeId: selectedValues[i] });
}
var jsonObject = { MasterIds: instructions };
$.ajax({
url: "/Admin/ApproveAllTimesheets",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(jsonObject),
success: function (result) {
console.log(result);
},
error: function (xhr, textStatus) {
if (xhr.status == 401) { alert("Session Expired!"); window.location =
"/Account"; }
else {
alert('Content load failed!', "info");
}
}
});
};
Controller:
public IActionResult ApproveAllTimesheets([FromBody]ValueContainer information)
Class Objects:
public class ValueContainer
{
public List<Value> MasterIds { get; set; }
}
public class Value
{
public Guid TimeId { get; set; }
}
Payload:
{"MasterIds":[{"TimeId":"ad98749f-9083-464b-aac2-0d685a7de809"}]}
UPDATE #1
As it turns out the fix is the way I was calling the function. Instead of the button onclick="SubAll()" I replaced that with a simple and used jQuery to intercept the click event, prevent it, and then call into the function...and now no 415 error.
View Button
<button id="ApproveAll" class="btn btn-success">Approve All</button>
View jQuery
$(document).ready(function () {
timesheet = $('#timesheet').DataTable({
responsive: {
details: {
renderer: function (api, rowIdx, columns) {
var data = $.map(columns, function (col, i) {
return col.hidden ?
'<tr data-dt-row="' + col.rowIndex + '"
data-dt-column="' + col.columnIndex + '">' +
'<td>' + col.title + ':' + '</td> ' +
'<td>' + col.data + '</td>' +
'</tr>' :
'';
}).join('');
return data ?
$('<table/>').append(data) :
false;
}
}
},
columnDefs: [
{
targets: 0,
orderable: false,
searchable: false,
checkboxes: true
},
{
targets: 5,
visible: false
},
{
targets: 6,
visible: false
}
],
order: [
[1, 'asc']
]
});
$('#ApproveAll').on('click',
function (e) {
var selectedValues =
$('#timesheet').DataTable().column(0).checkboxes.selected().toArray();
var instructions = []; //create array of objects
for (var i = 0; i < selectedValues.length; i++) {
instructions.push(selectedValues[i]);
}
var jsonObject = { MasterIds: instructions };
$.ajax({
url: "/Admin/ApproveAllTimesheets",
type: "POST",
contentType: "application/json;charset=utf-8",
data: JSON.stringify(jsonObject),
traditional: true,
statusCode: {
415: function () {
Response.redirect("/Admin/Index");
}
},
success: function (result) {
console.log(result);
},
error: function (xhr, textStatus, errorThrown) {
if (xhr.status == 401) { alert("Session
Expired!"); window.location = "/Account"; }
else {
alert('Content load failed!', "info");
}
}
});
e.preventDefault();
});
});

Use google maps autocomplete api with select2

I have a question about implementing Google Maps auto complete function with select2. I get this error in console "Uncaught SyntaxError: Unexpected token :".
$(document).ready(function() {
$(".adress-autocomplete").select2({
ajax: {
url: "https://maps.googleapis.com/maps/api/place/autocomplete/json",
type: "GET",
dataType: 'jsonp',
delay: 250,
data: function (params) {
return {
input: params.term, // search term
key: "MyKey"
};
},
processResults: function (data, params) {
params.page = params.page || 1;
return {
results: data["predictions"],
pagination: {
more: (params.page * 2) < data.total_count
}
};
},
cache: true
},
placeholder: 'Search Adress',
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 2,
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
function formatRepo (repo) {
if (repo.loading) {
return repo.text;
}
var markup = "<div class='select2-result-repository clearfix'>" +
"<div class='select2-result-title'>" + repo.description + "</div>";
return markup;
}
function formatRepoSelection (repo) {
return repo.description;
}
});
Json result:
https://jsonblob.com/1c69e57a-2220-11e8-b7b9-b3cbb530e512
Google doesn't like ajax request to their API, it's better if you override Select2 dataAdapter and use Google functions to call to the autocomplete API.
$.fn.select2.amd.define('select2/data/googleAutocompleteAdapter', ['select2/data/array', 'select2/utils'],
function (ArrayAdapter, Utils) {
function GoogleAutocompleteDataAdapter ($element, options) {
GoogleAutocompleteDataAdapter.__super__.constructor.call(this, $element, options);
}
Utils.Extend(GoogleAutocompleteDataAdapter, ArrayAdapter);
GoogleAutocompleteDataAdapter.prototype.query = function (params, callback) {
var returnSuggestions = function(predictions, status)
{
var data = {results: []};
if (status != google.maps.places.PlacesServiceStatus.OK) {
callback(data);
}
for(var i = 0; i< predictions.length; i++)
{
data.results.push({id:predictions[i].place_id, text: predictions[i].description});
}
data.results.push({id:' ', text: 'Powered by Google', disabled: true});
callback(data);
};
if(params.term && params.term != '')
{
var service = new google.maps.places.AutocompleteService();
service.getPlacePredictions({ input: params.term }, returnSuggestions);
}
else
{
var data = {results: []};
data.results.push({id:' ', text: 'Powered by Google', disabled: true});
callback(data);
}
};
return GoogleAutocompleteDataAdapter;
}
);
function formatRepo (repo) {
if (repo.loading) {
return repo.text;
}
var markup = "<div class='select2-result-repository clearfix'>" +
"<div class='select2-result-title'>" + repo.text + "</div>";
return markup;
}
function formatRepoSelection (repo) {
return repo.text;
}
var googleAutocompleteAdapter = $.fn.select2.amd.require('select2/data/googleAutocompleteAdapter');
$('.adress-autocomplete').select2({
width: '100%',
dataAdapter: googleAutocompleteAdapter,
placeholder: 'Search Adress',
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 2,
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
https://jsfiddle.net/angelmarde/perqpp9f/2/
It look like you are trying to filter by address, then you can change this line:
service.getPlacePredictions({ input: params.term }, returnSuggestions);
adding a type
service.getPlacePredictions({ input: params.term, types: ['address'] }, returnSuggestions);
You can see types here: https://developers.google.com/places/web-service/autocomplete#place_types

How to fetch particular data in column from JSON with keys

I am not sure how to fetch particular data in column from JSON with the help of keys. From ajax request i am getting data from the server but i want to store it in sqlite as the columns in server
$("#xxx").click(function()
{
var e = $("#mob").val();
var p = $("#key").val();
myDB.transaction(function(transaction)
{
transaction.executeSql('CREATE TABLE IF NOT EXISTS User_data (data)', [],
function(tx, result)
{
navigator.notification.alert("table created");
},
function(error)
{
navigator.notification.alert("error, table exists");
});
});
$.ajax
({
url: "http://192.168.1.4/sms/android.php",
type: "GET",
datatype: "json",
data: { type:'login', phone: e, name: p },
ContentType: "application/json",
success: function(response)
{
var valuesInArray = JSON.stringify(response);
var user_data = JSON.parse(valuesInArray);
for(var item in user_data.Users)
{
myDB.transaction(function(transaction)
{
transaction.executeSql('INSERT INTO User_data (id,date_closed) VALUES (item.id,item.date_closed)', [],
function(tx, result)
{
navigator.notification.alert("data inserted");
},
function(error)
{
navigator.notification.alert("error, table exists");
});
});
}
},
error: function(e)
{
alert('Got ERROR: ' + JSON.stringify(e));
}
});
});
here is the image of the data i am getting from the server
DATA IN ALERT BOX
here, i want to fetch each column in the database.
Thankx in advance.
<?php
header('Access-Control-Allow-Origin:*');
pg_connect("host=localhost port=5432 dbname=** user=** password=***");
if(isset($_GET['type']))
{
if($_GET['type'] == "login")
{
$mobile = $_GET['phone'];
$key = $_GET['name'];
$query = "select * from crm_lead where phone='$mobile' and id='$key'";
$result = pg_query($query);
while($myrow = pg_fetch_assoc($result))
{
$recipes[]=$myrow;
}
$output = json_encode(array('Users' => $recipes));
echo "'".$output."';";
}
}
else
{
echo "invalid";
}
pg_close();
?>
Why can't you use the response object directly since it's already a Json object?
var users = response.Users;
for(var i=0; i < users.length;i++)
{
var id = users[i].id;
//do something with id
}
$.ajax
({
url: "http://182.70.240.81:82/sms/android.php",
type: "GET",
datatype: "json",
data: { type: 'login', phone: 9770869868, name: 14 },
ContentType: "application/json",
success: function (response) {
var simpleJson = JSON.parse(response);
var shortName = 'db_test';
var version = '1.0';
var displayName = 'Test Information';
var maxSize = 65536; // in bytes
var db = openDatabase(shortName, version, displayName, maxSize);
db.transaction(function (txe) {
txe.executeSql('DROP TABLE User_data');
txe.executeSql('CREATE TABLE User_data(id INTEGER,date_closed TEXT)');
db.transaction(function (txe1) {
for (var i = 0; i < simpleJson.Users.length; i++) {
txe1.executeSql('INSERT INTO User_data (id,date_closed) VALUES (' + simpleJson.Users[i].id + ',"' + simpleJson.Users[i].date_closed + '")', [],
function (tx, result) {
alert("data inserted");
},
function (error) {
alert("error, table exists");
});
}
});
});
}
});
Remove Single Qoutaion from your json:

How do you mock MySQL (with node-orm2) in Node.js/Express?

I am using node.js/express with https://github.com/dresende/node-orm2 to use my MySQL database.
I am new to the node.js world and I am quite stuck so far, I don't know how to unit test (not integration test) a simple function.
Here is my server.js, loading my user model (ORM)
var express = require('express'),
orm = require('orm'),
config = require('./config/config.js'),
auth = require('./services/authentication'),
helper = require('./middlewares/helper.js'),
friends = require('./modules/friends.js');
var app = express();
app.use(orm.express('mysql://' + config.mysql.username + ':' + config.mysql.pwd + '#' + config.mysql.host + ':' + config.mysql.port + '/' + config.mysql.db, {
define: function(db, models, next) {
db.load("./models/models.js", function(err) { // loaded!
models.user = db.models.user;
});
}
}));
var middlewares = [auth.authenticate, helper.retrieveUser];
app.get('/friends', middlewares, friends.findActiveFriends);
app.listen(3000);
console.log('Listening on port 3000...');
here is the user model :
module.exports = function (db, cb) {
var User = db.define('user', {
uid : { type: 'number', rational: false, unique: true, required: true },
first_name : { type: 'text', size: 100, required: true },
last_name : { type: 'text', size: 100, required: true },
picture : { type: 'text', size: 255, required: false },
email : { type: 'text', size: 255, required: true },
creation_date : { type: 'date', time: true },
modification_date : { type: 'date', time: true }
}, {
methods: {
fullName: function () {
return this.first_name + ' ' + this.last_name;
}
},
hooks: {
beforeCreate: function (next) {
if (this.creation_date == undefined) {
this.creation_date = new Date();
}
if (this.modification_date == undefined) {
this.modification_date = new Date();
}
return next();
}
}
});
// CUSTOM FUNCTIONS
User.getByUid = function(uid, callback) {
this.find({ uid: uid }, function(err, users) {
if(err) callback(err);
if (users.length == 1) {
callback(null, users[0]);
} else {
callback('No user found with uid=' + uid);
}
});
};
User.hasMany("friends", User, {
status: { type: 'enum', values: ['pending', 'refused', 'active'] }
}, {
reverse: 'friendsrev', mergeId: 'user_id', mergeAssocId: 'friend_id'
});
return cb();
};
and here is my methods to find active friends in friends.js:
var _findActiveFriends = function(req, res) {
req.currentUser.getFriends({
status: 'active'
}, function(err, friends) {
if (err) throw err;
res.send(JSON.stringify(friends));
});
};
I would like to know how can I write a simple test (with mocha and sinon.js ?) by mocking the database connection and the request also. I need to mock the value of req.currentUser which is a user returned by the ORM in a middleware.
I just want to run unit tests and do not use a real DB or make some HTTP calls.
thanks for your help.
If you want to mock the req using sinon.js, you can do something like the following.
var sinon = require('sinon');
var friend = require('./friend');
it('some test', function(done) {
var req = {
currentUser: {
// Add all the properties/functions that you are concerned with here.
// and you can/should wrap them around sinon.spy().
// If you are not concerned with that function (i.e. you are not using it)
// then you can simply use sinon.stub() to return a stub function.
}
};
var res = {
send: sinon.spy(function(obj) {
assert.ok(obj); // yes object exists
done(); // end of test
};
};
var next = function() {};
friend.findActiveFriend(req, res, next);
});
This way you shouldn't be connecting to the model, which tests friend.js only.
Also, since I just noticed you are using orm.express, you may also want to simply mock req.models with the stubbed function you desire as above.