Autocomplete is returning undefined - jquery-ui

This is my jquery function:
$(function() {
$("#user").autocomplete({
source: 'spiderman/null/users.php',
minLength: 2
});
});
And when I start typing a minimum 2 letters in my
<input type="text" class="highlight" id="user" name="user"/>
It is showing a item list saying "undefined".
Seems like it is a invalid source, but I'm pretty sure it is valid, since I've maked include_once in the same dir, and the source script was loaded.
Here is my PHP code:
if( !$_GET['term'] ) {
die();
}
$return_arr = array();
$ac_term = "%".$_GET['term']."%";
$query = "SELECT `name` FROM `users` WHERE `name` LIKE :term";
$result = $conn->prepare($query);
$result->bindValue(":term", $ac_term);
$result->execute();
/* Retrieve and store in array the results of the query.*/
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
$row_array['name'] = $row['name'];
array_push($return_arr, $row_array);
}
/* Toss back results as json encoded array. */
echo json_encode($return_arr);
I've tested the PHP code also, and it works well: as for the term lol it does returned:
[{"name":"LolShit"},{"name":"Lolipop"},{"name":"Lolo"},{"name":"Lolololololololo"},{"name":"Loll"},{"name":"Pro Lol"}]

I think you either just want your JSON array to look like this:
["LolShit","Lolipop","Lolo","Etc..."]
Or if you want to use an object provide a label and value (which UI autocomplete expects):
[{"label":"LolShit","value":"LolShit"},{"label":"Lolipop","value":"Lolipop"},...]

I've added
$row_array['value'] = $row['name'];
And it worked... Dammit.
I hope it's ok to answer own question, lol.

Related

Need assistance reading the object returned by getRowId of MaterialReactTable

I am using MaterialReactTable in my application and following the Row Selection Option as outlined at this link: https://www.material-react-table.com/docs/guides/row-selection
The table is working fine and I am able to select the row I want and it returns the correct id but returns it in the format: rowSelection = {63d19bebc764a5587a48683a: true}. I am not familiar with this format.
I have tried everything I know but am unable to parse out the id from the object.
Please provide suggestion to parse out the id or suggest changes to make this solution work.
I have tried the other methods of row selection suggested on the page (useRef and '#tanstack/react-table') and could not get either to work so would like to stick to this method as I feel it is close.
Below is the code and options I am using with the MaterialReactTable
return (
<MaterialReactTable
columns={columns}
data={data}
enableRowSelection
onRowSelectionChange={setRowSelection}
enableMultiRowSelection={false}
//getRowId={(row) => row?._id }
getRowId={(originalRow) => originalRow._id}
initialState={{ showColumnFilters: true,
columnVisibility:
{ _id: false } }} //hide columns listed to start }}
manualFiltering
manualPagination
manualSorting
muiToolbarAlertBannerProps={
isError
? {
color: 'error',
children: 'Error loading data',
}
: undefined
}
muiTableBodyRowProps={({ row }) => ({
//add onClick to row to select upon clicking anywhere in the row
onClick: row.getToggleSelectedHandler(),
sx: { cursor: 'pointer' },
})}
onColumnFiltersChange={setColumnFilters}
onGlobalFilterChange={setGlobalFilter}
onPaginationChange={setPagination}
onSortingChange={setSorting}
rowCount={rowCount}
state={{
columnFilters,
globalFilter,
isLoading,
pagination,
showAlertBanner: isError,
showProgressBars: isRefetching,
sorting,
rowSelection
}}
/>
);
Given the format of the response, rowSelection = {63d19bebc764a5587a48683a: true}, I had originally assumed a key: value pair with the id being the key. My initial attempts to parse out the id as the key had failed. After trying a number of different options, I was able to use the Object.keys() function as follows:
console.log(Object.keys(rowSelection)); //used to view the key(s) returned
setCurrentRoom(Object.keys(rowSelection));
This code converted the id to a string in an array as follows: currentRoom = ['63d19bd9c764a5587a486836']

Free Text Entry in Angular Material mdAutoComplete

I want my angular material autocomplete to be a list of suggestions but not requirements. However I'm not sure how to implement as their is no clear example from the Angular Material docs.
In the example below my model is $ctrl.item.category
Clearly the example below is wrong, as my model is linked to md-selected-item, but this only works if I select an item. I want the user to be able to free enter the text if the item is not in the list. Basically how autocomplete already works in most browsers.
I see plenty of questions on how to disable this, but they are not trying to disable so much as clean up the left over text when an item is not selected. In these cases when an item is not selected then the model value is null, but text is left in the input.
I want the text left int he input to be the model value if the person does not select (or a match is not made).
md-autocomplete(
md-floating-label="Category Name"
flex="50"
md-input-name="category"
md-selected-item="$ctrl.item.category"
md-search-text="catSearch"
md-items="category in $ctrl.categories"
md-item-text="category"
md-min-length="0"
md-select-on-match=""
md-match-case-insensitive=""
required=""
)
md-item-template
span(md-highlight-text="catSearch" md-highlight-flags="^i") {{category}}
My options ($ctrl.categories) is an array of strings ['Food','Liqour'] and I wan the user to be able to use one of those or free enter Tables as their choice.
In this case you should link md-search-text to your model.
If you want to implement fuzzy search you have to write the filter method yourself. Look at this example:
template:
<md-autocomplete
md-items="item in $ctrl.itemsFilter()"
md-item-text="item.label"
md-search-text="$ctrl.query"
md-selected-item="$ctrl.selected"
>
<md-item-template>
<span md-highlight-text="$ctrl.query">{{item.label}}</span>
</md-item-template>
<md-not-found>
No item matching "{{$ctrl.query}}" were found.
</md-not-found>
<div ng-messages="$ctrl.myValidator($ctrl.query)">
<div ng-message="short">Min 2 characters</div>
<div ng-message="required">Required value</div>
</div>
</md-autocomplete>
controller:
var items = [ ... ];
ctrl.itemsFilter = function itemsFilter() {
return ctrl.query ? filterMyItems(ctrl.query) : items;
};
ctrl.myValidator = function (value) {
return {
short: value && value.length < 2,
required : value && value.length < 1,
};
};
then you just need to add filterMyItems method to filter your items
To improve the answer of #masitko, I have implemented the filter in a way, that it adds the query to the filtered list. So it becomes selectable and a valid option. So it's possible to make the autocomplete a suggestion box.
I'm using ES6 in my projects. But it should be easily adaptable to ES5 code.
myFilter() {
if (!this.query) return this.items;
const
query = this.query.toLowerCase(),
// filter items where the query is a substing
filtered = this.items.filter(item => {
if (!item) return false;
return item.toLowerCase().includes(query);
});
// add search query to filtered list, to make it selectable
// (only if no exact match).
if (filtered.length !== 1 || filtered[0].toLowerCase() !== query) {
filtered.push(this.query);
}
return filtered;
}

ZF2 : Change a row field in ResultSet

I want to change a row field in my ResultSet before returning it to my Controller.
$resultSet->buffer();
foreach ($resultSet as $row) {
$row->foo = $newvalue;
}
return $resultSet;
Problem is, when I use the buffer() function I can indeed loop over my ResultSet and make some changes on my rows, but once the loop ends all changes are gone.
I tried to set up a reference on $row :
foreach ($resultSet as &$row)
But then caught the following exception :
Fatal error: An iterator cannot be used with foreach by reference
I also tried to change resultSet to array but the same problem occurs.
Have I missed something ?
I don't think it is possible via the usual ResultSet usage. The array solution might work only if you are going to use the array in loops (foreach() in this case).
From any Table class -
$arr_resultSet = array();
foreach ($resultSet as $row) {
$row->foo = $newvalue;
//Object is assigned instead of converting it to an array.
$arr_resultSet[] = $row;
}
return $arr_resultSet;
Usage of this array in controller or view file -
//Here you can access that $row object as if the $resultSet was never converted to array.
foreach($arr_resultSet as $row) {
echo $row->foo;
}
No need of buffer(). I hope it works for now. Will definitely search for a proper solution.

Convert Select2 input to tokens

Does the Select2 jQuery plug-in have a built-in function for converting strings to tokens?
I want to be able to call this tokenizing function when the user pastes strings into a Select2 field so that the pasted input becomes tokens.
I think I have solved the question myself with the following code:
// force tokenizing of Select2 auto-complete fields after pasting
$('body').on('paste', '.select2-input', function() {
// append a delimiter and trigger an update
$(this).val(this.value + ',').trigger('input');
});
This assumes that commas are set as delimiters in the plug-in's "tokenSeparators" initialization setting.
For 4.0.1 version:
$('#my-select').data('select2').dataAdapter.$search.val("tag1,tag2,").trigger("input");
This will add two tags: tag1 and tag2 (note trailing ,).
Important: you should add data: [] into select2 init parameters.
Use an input type text, and assign the select2 to it. Like
<input type="text" id="makeTokens" />
and then in javascript
$("#makeTokens").select2({
placeholder: "Paste data",
tags: ["red", "green", "blue"],
tokenSeparators: [",", " "]
});
in the tags, you can assign any values that you want it to display as select options and use the tokenSeperators to seperate the text on commas or spaces etc.
Note: The resultant input value will be comma seperated tokens.
For some reason Donald's solution didn't work for me (maybe newer versions of select2 behaves differently). This is what worked for me:
$('body').on('paste', '.select2-input', function (e) {
var pasteData = (e.originalEvent || e).clipboardData.getData('text/plain') || '';
$(this).val(pasteData + ',');
e.preventDefault();
});
Since at the point the event was triggered the value of .select2-input was an empty string, I extractacted the pasted string from the event object. Apparently the default select2 for copying action was still triggering after this, so I had to add e.preventDefault(); to stop it from running and messing up the input.
just run this jQuery which takes the separatoes from options.tokenSeparators directly, and applies for all select2 instances in the page automatically:
$(document).on('paste', 'span.select2', function (e) {
e.preventDefault();
var select = $(e.target).closest('.select2').prev();
var clipboard = (e.originalEvent || e).clipboardData.getData('text/plain');
var createOption = function (value, selected) {
selected = typeof selected !== 'undefined' ? selected : true;
return $("<option></option>")
.attr("value", value)
.attr("selected", selected)
.text(value)[0]
};
$.each(
clipboard.split(new RegExp(select.data('select2').options.options.tokenSeparators.map(function (a) {
return (a).replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}).join('|'))),
function (key, value) {
if (value && (!select.val() || (select.val() && select.val().indexOf('' + value) == -1))) {
select.append(createOption(value));
}
});
select.trigger('change');
});

jQuery or JavaScript getting the value of .each function

I have this jQuery .each function so I can traverse all the UL hmtl tags. Then I will get there id attribute. But the problems is, How can I get each value and place it to another variable so I can use it to .sortable UI function. Here is my code:
jQuery('.b ul').each(function(){
jQuery(this).attr('id');
});
example: the output of the .each function when I do alert is "0 1 2". How can I place it to another variable? So it would be use in:
jQuery(variable here).sortable(){ });
The code above will get the ID attribute. Anyone who can help?
Thanks,
Justin
No need to use the ID's at all. You can provide jQuery's $() function with more than just ID's:
$('.b ul').sortable();
Or if you are using multiple libraries (jQuery, MooTools, etc.):
jQuery('.b ul').sortable();
Any of these should work
Save the jquery array to a variable to act on later:
var $lists = $(".b ul")
$lists.sortable()
Act on the selector directly:
$(".b ul").sortable()
Don't do this:
var ids = []
$(".b ul").each(function() {
var id = $(this).attr("id")
ids.push(id)
})
var selector = "#" + ids.join(", #")
$(selector).sortable()

Resources