JqGrid + Autocomplete - php

I'm having trouble implementing autocomplete in jqgrid. I've walked researching, alias until I based this question on a site that currently do not meet. The problem is this, I have to use the autocomplete several times throughout the application I'm developing. And now I have this function:
Javascript:
function autocomplete_element(value, options) {
var $ac = $('<input type="text"/>');
$ac.val(value);
$ac.autocomplete({
source: function(request, response)
{
$.getJSON("autocomplete.php?id=estrategico",
{ q: request.term }, response);
}
});
return $ac;
}
Jqgrid:
jQuery("#obj_oper_org").jqGrid({
(...)
{name:'COD_OBJ_EST',index:'COD_OBJ_EST', hidden: true, editable:true, editrules:{required:true, edithidden:true}, edittype : 'custom', editoptions : {'custom_element' : autocomplete_element}},
What was intended to pass a parameter to the javascript function more in order not to repeat forever the same function for each field because I need to be constantly changing url. Is it possible to make something of the genre? Sorry for the question but I do not have much experience in javascript, so I have some difficulties

First of all you don't need to use edittype : 'custom' to be able to use jQuery UI Autocomplete. Instead of that you can use just dataInit.
You can define myAutocomplete function for example like
function myAutocomplete(elem, url) {
setTimeout(function () {
$(elem).autocomplete({
source: url,
minLength: 2,
select: function (event, ui) {
$(elem).val(ui.item.value);
$(elem).trigger('change');
}
});
}, 50);
}
and then use
{ name:'COD_OBJ_EST', hidden: true, editable: true,
editoptions: {
dataInit: function (elem) {
myAutocomplete(elem, "autocomplete.php?id=estrategico");
}
}}
Be careful that the name of parameter which will be send to the server is the standard name term instead of the name q which you currently use. I personally don't see any need to change the default name of the parameter.

Related

Return array/object to jquery script from AJAX

Hello all and thanks in advance,
Short story, I am using a plugin to dynamically populate select options and am trying to do it via an ajax call but am struggling with getting the data into the select as the select gets created before the ajax can finish.
First, I have a plugin that sets up different selects. The options input can accept an array or object and creates the <option> html for the select. The createModal code is also setup to process a function supplied for the options input. Example below;
$('#modalAccounts').createModal({
{
component: 'select',
options: function () {
let dueDate = {};
for (let i = 1; i < 32; i++) {
dueDate[i] = i;
}
return dueDate;
}
}
});
What I am trying to do is provide an object to the options input via AJAX. I have a plugin called postFind which coordinates the ajax call. Items such as database, collection, etc. are passed to the ajax call. Functions that should be executed post the ajax call are pass through using the onSuccess option.
(function ($) {
$.extend({
postFind: function () {
var options = $.extend(true, {
onSuccess: function () {}
}, arguments[0] || {});
options.data['action'] = 'find';
$.ajax({
url: "../php/ajax.php",
type: "POST",
data: options.data,
statusCode: {
404: function () {
alert("Page not found");
}
},
success: function (result) {
var obj = $.parseJSON(result);
if (obj.success) {
if (typeof options.onSuccess === 'function') {
options.onSuccess.call(this, obj);
}
}
},
error: function (xhr, text, err) {
console.log(err);
}
});
}
});
}(jQuery));
The plugin works fine as when I look at the output it is the data I expect. Below is an example of the initial attempt.
$('#modalAccounts').createModal({
{
component: 'select',
options: function () {
$.postFind({
data: {
database: 'dashboard',
collections: {
accountTypes: {
where: {status: true}
}
}
},
onSuccess: function (options) {
let dataArray = {};
$.each(options, function (key, val) {
dataArray[val._id.$oid] = val.type;
});
return dataArray;
}
})
}
}
});
In differnt iterations of attempting things I have been able to get the data back to the options but still not as a in the select.
After doing some poking around it looks like the createModal script in executing and creating the select before the AJAX call can return options. In looking at things it appears I need some sort of promise of sorts that returns the options but (1) I am not sure what that looks like and (2) I am not sure where the promise goes (in the plugin, in the createModal, etc.)
Any help you can provide would be great!
Update: Small mistake when posted, need to pass the results back to the original call: options.onSuccess.call(this, obj);
I believe to use variables inside your success callback they have to be defined properties inside your ajax call. Then to access the properties use this inside the callback. Like:
$.ajax({
url: "../php/ajax.php",
type: "POST",
data: options.data,
myOptions: options,
statusCode: {
404: function () {
alert("Page not found");
}
},
success: function (result) {
var obj = $.parseJSON(result);
if (obj.success) {
if (typeof this.myOptions.onSuccess === 'function') {
this.myOptions.onSuccess.call(this);
}
}
},
error: function (xhr, text, err) {
console.log(err);
}
});
It's not clear to me where the problem is without access to a functional example. I would start with a simplified version of what you want to do that demonstrates the proper functionality. My guess is the callbacks aren't setup exactly correctly; I would want to see the network call stack before making a more definitive statement. A few well-placed console.log() statements would probably give you a better idea of how the code is executing.
I wrote and tested the following code that removes most of the complexity from your snippets. It works by populating the select element on page load.
The HTML file:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<select data-src='test.php' data-id='id' data-name='name'></select>
</body>
</html>
<html>
<script>
$('select[data-src]').each(function() {
var $select = $(this);
$select.append('<option></option>');
$.ajax({
url: $select.attr('data-src'),
data: {'v0': 'Alligator', 'v1': 'Crocodile'}
}).then(function(options) {
options.map(function(option) {
var $option = $('<option>');
$option
.val (option[$select.attr('data-id')])
.text(option[$select.attr('data-name')]);
$select.append($option);
});
});
});
</script>
And the PHP file:
<?php
header("Content-Type: application/json; charset=UTF-8");
echo json_encode([
[ 'id' => 0, 'name' => 'Test User 0' ],
[ 'id' => 3, 'name' => $_GET['v0'] ],
[ 'id' => 4, 'name' => $_GET['v1'] ]
]);
Here's a fiddle that also demonstrates the behavior.

typeahead bootstrap auto suggestion for ajax function

I'm using typeahead auto suggestion for my application but the problem is ajax function exists in bookingAjaxFunc function and bookingAjaxFunc code is
function bookingAjaxFunc(url, bookingId, jsonCall) {
switch(jsonCall) {
case 'Add':
values = $('.booking-form').serializeArray();
break;
case 'autoSuggestion':
values = {bookingId: bookingId, jsonCall: jsonCall};
break;
}
$.ajax({
url: url,
type: 'POST',
dataType: 'json',
data: values,
cache: false,
success: function(data) {
switch(jsonCall) {
case 'Add':
console.log(data);
break;
case 'autoSuggestion':
console.log(data);
break
}
}
});
}
this is my ajax function which is working fine in insert, update, delete and other cases but now I want to call this function in typeahead how could I do this? and my typeahead function is working fine in predefined values but now I want to call my bookingAjaxFunc I couldn't figure out where to call my function, and remember this function is copy from an example and I paste it here as it as.
function substringMatcher(strs) {
return function findMatches(q, cb) {
var matches, substrRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strs, function (i, str) {
if (substrRegex.test(str)) {
// the typeahead jQuery plugin expects suggestions to a
// JavaScript object, refer to typeahead docs for more info
matches.push({ value: str });
}
});
cb(matches);
};
}
var states = ['Alabama', 'Alaska'];
$('.autoSuggestion').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'states',
displayKey: 'value',
source: substringMatcher(states)
});
The bookingAjaxFunc function which create for my ajax call so where I use my this code for passing values to my function and use my case
var url = $("#do").val();
bookingAjaxFunc(url, '', 'autoSuggestion');
I also try to add remote below source but didn't work.
Thanks

Linked/chained MagicSuggest dropdowns?

I am trying to build a set of linked/chained multiselect boxes using MagicSuggest and a php query. So, first I build a MagicSuggest box with a function for when ms1 is changed:
$(document).ready(function() {
var ms1 = $('#ms1').magicSuggest({
data: 'datams1.php',
displayField: 'name' });
$(ms1).on('selectionchange', function(event, combo, selection){
run(selection);});
});
Then I build a new MagicSuggest box by running a php query that returns a json object:
function run(country) {
$.getJSON("query.php", { id: country[0].id}, callbackFuncWithData );
}
function callbackFuncWithData(region) {
var ms2 = $('#ms2').magicSuggest({
data: region,
displayField: 'name'
});
}
This works once I make an initial selection, but does not update if I change the selection. I have checked and within my "callbackFuncWithData" I am producing an updated "region" json object. So it might just be that I need to refresh/reload my #ms2 object.
My questions are:
Is there a way to force an refresh of the MagicSuggest data?
Is there a better/cleaner/more efficient way to use the results of one MagicSuggest box to query and return the data for a second, linked MagicSuggest box?
Thanks!
use setData() method to dynamically set the data when needed.
you can always use a library like angular to bind the component properties together.
This code makes 2 linked combos with the same data, but one of them shows the "name" field and the other one shows the "name1" filed.
function reflectSelection(ms1, ms2){
var val = parseInt(ms1.getValue());
var val1 = parseInt(ms2.getValue());
if(!isNaN(val)){
if(val != val1){
ms2.clear(true);
ms2.setSelection(ms1.getSelection());
}
}
else
{
ms2.clear(true);
}
}
var msName = $('#ms-onselectionchange').magicSuggest({
maxSelectionRenderer: function(){ return ''; },
useTabKey: true,
noSuggestionText: '',
strictSuggest: true,
maxSelection: 1,
allowFreeEntries: false,
placeholder : '',
data: [{'id':0, 'name':'Paris', 'name1':'Paris5'}, {'id':1, 'name':'New York', 'name1':'New York5'}],
});
var msName1 = $('#ms-onselectionchange1').magicSuggest({
maxSelectionRenderer: function(){ return ''; },
useTabKey: true,
noSuggestionText: '',
displayField: 'name1',
strictSuggest: true,
maxSelection: 1,
allowFreeEntries: false,
placeholder : '',
data: [{'id':0, 'name':'Paris', 'name1':'Paris5'}, {'id':1, 'name':'New York', 'name1':'New York5'}],
});
$(msName).on('selectionchange', function(e,m){
reflectSelection(msName, msName1);
});
$(msName1).on('selectionchange', function(e,m){
reflectSelection(msName1, msName);
});

ajaxFileUpload on xhr.setRequestHeader is not a function

In my footer.php I have this code which i needed for my api references
<script type="text/javascript">
/** Override ajaxSend so we can add the api key for every call **/
$(document).ajaxSend(function(e, xhr, options)
{
xhr.setRequestHeader("<?php echo $this->config->item('rest_key_name');?>", "<?php echo $this->session->userdata('api_key')?>");
});
</script>
It works fine in my project without any error but when I started working on file upload and I'm using ajaxfileupload to upload file, I got this error whenever i upload the file.
TypeError: xhr.setRequestHeader is not a function
xhr.setRequestHeader("KEY", "123456POIUMSSD");
Here is my ajaxfileuplod program code:
<script type="text/javascript">
$(document).ready(function() {
var DocsMasterView = Backbone.View.extend({
el: $("#documents-info"),
initialize: function () {
},
events: {
'submit' : 'test'
},
test: function (e) {
e.preventDefault();
var request = $.ajaxFileUpload({
url :'./crew-upload-file',
secureuri :false,
fileElementId :'userfile',
dataType : 'json',
data : {
'title' : $('#title').val()
},
success : function (data, status)
{
if(data.status != 'error')
{
$('#files').html('<p>Reloading files...</p>');
refresh_files();
$('#title').val('');
}
alert(data.msg);
}
});
request.abort();
return false;
}
});
var x = new DocsMasterView();
});
</script>
Can anyone here fix my problem. Any suggestion/advice in order to solve my problem.
As I understand from your comments, setRequestHeaders works fine with regular ajax calls. At the same time it is not available when ajaxFileUpload is used. Most likely that is because transport method does not allow to set headers (for instance, in case when iframe is used to emulate upload of files in ajax style) . So, possible solution is to place a key into your form data:
$(document).ajaxSend(function(e, xhr, options)
{
if(xhr.setRequestHeader) {
xhr.setRequestHeader("<?php echo $this->config->item('rest_key_name');?>", "<?php echo $this->session->userdata('api_key')?>");
else
options.data["<?php echo $this->config->item('rest_key_name');?>"] = "<?php echo $this->session->userdata('api_key')?>";
});
Note: I'm not sure if options.data is a correct statement, just do not remember structure of options object. If proposed code does not work - try to do console.log(options) and how
to get an object with data that should be posted (it might be something like options.formData, I just do not remember exactly)
And on server side you will just need to check for key in headers or form data.

Why this mmediately invoked functions is not working properly

I am using immediately invoked functions pattern, but this is not passing the id
1.When the user clicks on $user, id is passed and the chat window appears
echo "<div class='boxbottom'><a href='#' onclick=chat_com_one($id);> >$user</a><br></div>";
2.Function chatcom_load_one keep checking, if there is any message from the id passed to chatcom_load_one function.
But the problem is that onclick function do passes the id but immediately invoked function did not pass the id to the post function.
Also sending the message is slow?
Please help or suggest any alternate approach, I think error is in the chat_load_one pattern.
function chat_com_one(id) {
$('#chatcom').show('fast');
(function chatcom_load_one(id) {
$.post('sendchat2.php', {
option: 'chatcom_load_one',
tocom: id
}, function (data) {
$('#chatcom #commid #commidwin').html(data);
setTimeout(chatcom_load_one(id), 1000);
});
}());
$('#chatcom_send').click(function () {
var text = document.getElementById('chatcom_text').value;
$.post('sendchat2.php', {
option: 'chat_com_send_one',
text: text,
tocom: id
}, f
function (data) {
document.getElementById('chatcom_text').value = '';
});
});
}
send function on my server
if($_REQUEST['option']=='chat_com_send_one'){
$session=new $session;
$text=mysqli_real_escape_string($db3->connection,$_POST['text']);
$tocom=mysqli_real_escape_string($db3->connection,$_POST['tocom']);
$sql=mysqli_query($db3->connection,"INSERT INTO chat_com(fro,tocom,mesg,time) VALUES ('$session->userid','$tocom','$text',CURRENT_TIMESTAMP)");
}
First off, I notice two problems:
You have a syntax error in the parameter list to $.post
You probably don't want to do this: setTimeout(chatcom_load_one(id), 1000);
Here's an updated version of your code with these errors fixed:
function chat_com_one(id) {
$('#chatcom').show('fast');
(function chatcom_load_one(id) {
$.post('sendchat2.php', {
option: 'chatcom_load_one',
tocom: id
}, function (data) {
$('#chatcom #commid #commidwin').html(data);
setTimeout(function () {
chatcom_load_one(id);
}, 1000);
});
}());
$('#chatcom_send').click(function () {
var text = document.getElementById('chatcom_text').value;
$.post('sendchat2.php', {
option: 'chat_com_send_one',
text: text,
tocom: id
},
function (data) {
document.getElementById('chatcom_text').value = '';
});
});
}
Also, since you're using jQuery, you can simplify document.getElementById.... Another updated version (with some more changes to make it more readable):
function chat_com_one(id) {
$('#chatcom').show('fast');
(function chatcom_load_one(id) {
$.post('sendchat2.php', {
option: 'chatcom_load_one',
tocom: id
}, function (data) {
$('#commidwin').html(data);
setTimeout(function () {
chatcom_load_one(id);
}, 1000);
});
}(id));
$('#chatcom_send').click(function () {
var text = $('#chatcom_text').val();
$.post('sendchat2.php', {
option: 'chat_com_send_one',
text: text,
tocom: id
},
function (data) {
$('#chatcom_text').val('');
});
});
}
These are just a few cleanups, there may be others.
Edit:
Added devnull69's insight to my final updated code. Hopefully it's useful (accept his answer if this was the problem).
Edit: Other notes
Why are you doing $.post in chatcom_load_one? It would make much more sense as a $.get, and the query parameters would still be sent. It's not really a problem per se, but it's bad style. This should probably be in a file called getchat.php or something instead of doing what I expect is looking for the text parameter.
Also, I don't know the implementation of sendchat2.php, but you should probably reduce the timeout. Try something like 250ms or so. That's not going to overload the server and it'll improve response time.
In addition to the previously mentioned problems you invoke the immediately executed function without any parameter. You will have to add the (id) parameter to the function call in order to hand over the id element to its local copy inside the function.
(function chatcom_load_one(id) {
...
}(id));

Categories