jquery-ui autocomplete using multiple field values - jquery-ui

I have a bunch of fields (first name, last name, etc) and I want to be able to pass the values of any that are filled or partially filled to the autocomplete server side so I can use them in the query.

I did this by updating the autocomplete "source" on any change of focus on the various fields, or on the autocomplete "select" event.
jQuery('#people_new_user input[type="text"]').each(
function(index, element) {
var field = element.name;
jQuery(element)
.focus(setSourceUser)
.autocomplete({
source: "/cf/AutoComplete/People?current="+field,
select: selectUser
});
});
The code above sets up a "focus" event handler called "setSourceUser" and a handler for the autocomplete "select" event called "selectUser".
function setSourceUser(event)
{
var endPart = "";
jQuery('#people_new_user input[type="text"]').each(
function(index, ielement) {
var ifield = ielement.name;
var ival = ielement.value;
if (ival != '')
{
endPart += '&field=' + ifield;
endPart += '&value=' + ival;
}
}).each(
function(index, element) {
var field = element.name;
jQuery(element)
.autocomplete("option", "source",
"/cf/AutoComplete/People?current="+field+endPart);
});
}
The above "setSourceUser" function gets all the values from all the fields (in the first "each" function) and builds a "endPart" for the source, and then sets up the autocomplete "source" option for each field. I'm not going to show the "select" callback because it does other stuff that's not relevant to this issue, and then calls "setSourceUser". The source ends up being something like /cf/AutoComplete/People?current=last_name&field=first_name&value=p&field=last_name&value=tomblin as well as the "term" value that autocomplete itself supplies.
On the server side, my function (written in Mason and Perl in this case) uses the &field=foo&value=bar pairs (skipping the ones where field == current, because autocomplete passes in the more current value in term) in "LIKE" sql statements. Then I return the found results in JSON. (If there are more than 50 results, I don't bother because the list would be too long.)
% $r->content_type('application/json');
<% JSON::to_json( \#suggestions, { utf8 => 1, allow_blessed => 1,
convert_blessed => 1, } ) |n %>
% $m->abort;
<%ARGS>
#field => undef
#value => undef
$current => undef
$term => undef
</%ARGS>
<%INIT>
use RTx::SearchBuilder::Records::Peoples;
$current =~ s/people_//g;
my $people = RTx::SearchBuilder::Records::Peoples->new(Handle => CFHandle());
my $fn = scalar(#field);
for my $i (0...$fn-1)
{
my $f = $field[$i];
next if !defined($f);
my $v = $value[$i];
if ($f ne $current)
{
$people->Limit(
FIELD => $f,
OPERATOR => 'LIKE',
VALUE => '%'.$v.'%',
ENTRYAGGREGATOR => 'AND');
}
}
$people->Limit(
FIELD => $current,
OPERATOR => 'LIKE',
VALUE => '%'.$term.'%',
ENTRYAGGREGATOR => 'AND');
my #suggestions;
# If there are too many results, skip it and make them narrow it down a bit
# more
if ($people->Count < 50)
{
while (my $person = $people->Next)
{
my $suggestion = { label => $person->$current, value => $person };
push #suggestions, $suggestion;
}
}
</%INIT>

Related

IN operator does not seem to work with primary key fields

Using MySQL.
I have the following entity:
import { Column, Entity, ValueTransformer } from 'typeorm';
const ormIdTransformer: ValueTransformer = {
to: (value: any) => (value !== undefined && value !== null ? Number(value) : value),
from: (value: any) => (value !== undefined && value !== null ? String(value) : undefined),
};
#Entity()
export class User {
#Column({ type: 'int', transform: ormIdTransformer, primary: true })
id: string;
#Column({ type: 'int', transform: ormIdTransformer })
profileId: string;
// ...
}
Please note that profileId is not mapped as a relation here.
In my app, I have a custom UserRepository, and it has access to an entityManager (both internally, and externally, in case the operation is running inside a transaction).
I'm trying to search for all users that have specific IDs and a specific profile (also by ID):
// Just an example
const profileId = '1';
const userIds = ['1', '2', '3', /* ... */];
const ids = await entityManager.find(User, { where: { profileId, id: In(userIds) }, select: ['id'] });
I'd expect TypeORM to generate a query similar to the following:
SELECT `User`.`id` from `User` `User` WHERE `User`.`profileId` = ? AND `User`.`id` IN ?`
-- Parameters: [1, [1, 2, 3, ...]]
Instead, TypeORM seems to completely ignore the FindOperator (the In) I provided, and just passes In(userIds) through as if it was a normal value. This FindOperator goes directly to my ValueTransformer, which I think is not correct.
But that's not the worse of it. By activating query logging, I see that TypeORM generates the following query:
SELECT `User`.`id` AS `User_id` FROM `User` `User` WHERE `User`.`profileId` = ? AND `User`.`id` = ?
-- Parameters: [2, NaN]
The operation obviously fails with a database error: QueryFailedError: ER_BAD_FIELD_ERROR: Unknown column 'NaN' in 'where clause'.
Notice how the condition for the id column is not being applied correctly: it should be IN, not =.
Am I doing something wrong?
After some debugging, I found out that the problem was related to the custom transformer I was implementing for my IDs.
QueryBuilder has special logic to take care of FindOperator, but that only works if ColumnMetadata.getEntityValue (which is called in QueryBuilder) actually returns an operator. But ColumnMetadata.getEntityValue lacks the logic to deal with FindOperator; instead of applying the transformation to the operator's wrapped value, it applies the transformation to the operator itself.
With that knowledge, I looked up for problems related to FindOperator and custom transformations, and found an answer to a similar question. That helped me implement a transformation process that actually works with FindOperators.
Long story short, turns out I had to reconstruct the entire operator, and transform the values wrapped in it myself. This is what I came up with:
import { FindOperator, FindOperatorType, ValueTransformer } from 'typeorm';
const idFromDb = (value: any) => {
if (value === undefined || value === null) {
return undefined;
}
return String(value);
};
const idToDb = (value: any) => {
if (value === undefined || value === null) {
return undefined;
}
if (Array.isArray(value)) {
return value.map(idToDb);
}
if (value instanceof FindOperator) {
return new FindOperator(
value.type as FindOperatorType,
idToDb(value.value),
value.useParameter,
value.multipleParameters,
);
}
return Number(value);
};
export const ormIdTransformer: ValueTransformer = {
to: idToDb,
from: idFromDb,
};

ui-grid: How to use function for columnDefs

For some reason I need to create headers dynamically because of component I used.
So I have a function which and that function I want to use to provide values to columnDefs
ctrl.getColumnDefs = () => {
let columns = []
if (name === 'deamon') {
var normalCol = {
field: 'name',
enableSorting: true,
cellTooltip: (row, col) => row.entity[col.field],
enableCellEdit: false
};
return columns.push(normalCol);
}
Then I am using
ctrl.grid = {
columnDefs: getColumnDefs()
}
Which is throwing TypeError: self.options.columnDefs.forEach is not a function
You are returning the value of push. That returns the new length of the array as per docs here.
You probably want to return columns instead of push.
Probably you want this
columns.push(normalCol)
return columns

watch expression is not picking up on model change from ng-change

I have the following
Rails HAML:
= select_tag "some-class",
options_for_select([['None', '']], ''),
{ class: 'some-other-class',
'ng-model' => 'someModel',
'ng-options' => 'option.name for option in someList',
'ng-change' => 'updateSelected()'}
Angular Controller:
scope.updateSelected = ->
#logic for updating model lives here. Model updates successfully by using some values defined within scope. Includes the following:
scope.someModel = "some_new_value"
Angular Directive:
SomeClassDirective= ->
restrict: 'C'
link: (scope, element, attrs) ->
monitorFormFields = (newValue, oldValue) ->
console.log "this is the inner function call"
#logic for setting the inner _destroy field lives here
scope.$watch 'someModel', monitorFormFields
However, when the Select List value is changed, 'this is the inner function call' never prints.(it does print when the directive first initializes, ie at page load). My question therefore is: Why isn't the $watch expression triggering, and how do I get it to trigger?
Thanks!
With this HTML:
<select class="some-class" ng-model="someModel"
ng-options="option.name for option in someList"></select>
Here is a directive that will watch for a change to someModel:
myApp.directive('someClass', function () {
return {
restrict: 'C',
link: function (scope, element, attrs) {
var monitorFormFields = function (newValue, oldValue) {
console.log("this is in the inner function call");
}
scope.$watch('someModel', monitorFormFields);
}
}
});
Controller:
$scope.someList = [{ name: 'name1' }, { name: 'name2' }];
Note that you don't need to call a controller method to update someModel -- Angular does that automatically for us because of the ng-model attribute. So, the directive only needs to $watch for a change to that $scope property.
Fiddle.
I would like to from the element fetch a sibling with [_destroy] in the name and set it to either "0" or "1" depending on the value of the select box.
A more Angular approach would be to have model properties control whether "0" or "1" is displayed. E.g., in your controller:
$scope.destroy1 = "0";
$scope.destroy2 = "0";
In your HTML:
<div>{{destroy1}}</div>
<div>{{destroy2}}</div>
In monitorFormFields() you can change the values of these scope properties, and the view will automatically update -- there is no need to "find" siblings or update .val()ues.

Using PagedList to add paging function to ASP MVC3 website

One of the search functions to our website returns far too many results for one page to handle, so I am trying to add the paging function as provided by here: https://github.com/TroyGoode/PagedList
The solution builds properly and the page will load as well, however when I try to conduct a search a "NotSupportedException" is thrown on the page's controller/Index() method:
The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
Visual Studio 2010 points to the return statement when this exception is thrown. This is only my second day working in ASP MVC so any and all suggestion are welcome. Thank you!
case "name":
//if no comma, do a combined search by last name and by corporate name.
searchString = searchString.ToUpper();
var lastAgents =
db.Agent.OrderBy(s => s.LastName).Where(s => s.LastName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification).Include(a => a.SymetraNumberToAgentId);
//end new code
var corp2Agents =
db.Agent.OrderBy(s => s.CorporateName).Where(s => s.CorporateName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification);
if ((corp2Agents.Count() == 0) & (lastAgents.Count() == 0)) ViewBag.ErrorMessage = "None found in search for Last Names and Companies beginning with " + search1;
else ViewBag.Message = "Results of Last Name and Company Name search. Found " + (corp2Agents.Count() + lastAgents.Count()).ToString();
pageNumber = (page ?? 1);
return View(lastAgents.Union(corp2Agents).ToPagedList(pageNumber, pageSize));
Took forever but I found the answer. Both these statements
var lastAgents =
db.Agent.OrderBy(s => s.LastName).Where(s => s.LastName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification).Include(a => a.SymetraNumberToAgentId);
//end new code
var corp2Agents =
db.Agent.OrderBy(s => s.CorporateName).Where(s => s.CorporateName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification);
contain an OrderBy, however this is necessary in the Union statement as well. The final "return" statement is as follows:
return View((lastAgents.Union(corp2Agents)).OrderBy(s => s.sNumber).ToPagedList(pageNumber, pageSize));
Try adding the .OrderBy(s => s.sNumber) in the controller like this:
var lastAgents =
db.Agent.Where(s => s.LastName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification).Include(a => a.SymetraNumberToAgentId).OrderBy(s => s.sNumber);
//end new code
var corp2Agents =
db.Agent.Where(s => s.CorporateName.ToUpper().StartsWith(searchString)).Include(
a => a.AgentIdentification).OrderBy(s => s.CorporateName);

Need Help to write a jasmine spec

Hello I am trying to write a jasmine test for a backbone view and one of its function. I want to test the correct behavior of the function in the case a user checks a checkbox in the rendered view then submit.
Here is the tests :
describe("buildCI()", function() {
describe("with a category selection allowed's quidget model", function() {
it("returns a CoacheeIssue model with the selected categories", function() {
selection_allowed = true;
lcc_selection_allowed = false;
var view = new Rails3DeviseRspecCucumber.Views.CategoryPicker({
collection: categoriesCollection,
answers: answers,
category_ids: category_ids,
credentials: credentialsCollection,
user_hash: user_hash,
selection_allowed: selection_allowed,
lcc_selection_allowed: lcc_selection_allowed
});
// render the view so we can manipulate its DOM elements
view.render();
elDebug = $(view.$el);
// Check programmatically a category checkbox
$(elDebug.find('input.category-checkbox#5061c6a48624da6f4100000a')[0]).prop('checked', true);
// call the buildCI() function and check the result
result = view.buildCI();
console.log(result);
expect(result.get('categories')).toContain('category one');
expect(result.get('categories')).not.toContain('category two');
})
})
Unfortunately the test fails with this message : Expected [ ] to contain 'category one'.
I know it is not a coding error, because it is working in live, I would just like to know how to test it.
Here is the function :
buildCI: () ->
# prepare the category_ids and categories (names) attributes
if #selection_allowed
selectedCategories = []
for checkbox in $('input.category-checkbox')
checkboxEl = $(checkbox)
if checkbox.checked
selectedCategories.push(_.find(#collection.models, (model) ->
model.id == checkboxEl.attr('id')
))
category_names = _.map(selectedCategories, (category) -> category.get('name'))
category_ids = _.map(selectedCategories, (category) -> category.get('_id'))
else
category_names = _.map(#collection.models, (category) -> category.get('name'))
category_ids = _.map(#collection.models, (category) -> category.get('_id'))
return new Rails3DeviseRspecCucumber.Models.CoacheeIssue({
is_solved: false, status: 'active', solution_value_estimate: '',
answers: #answers, categories: category_names, category_ids: category_ids
})
Thanks in advance
Is your selector too strict? I notice that it is:
$(elDebug.find('input.category-checkbox#5061c6a48624da6f4100000a')[0]).prop('checked', true);
but perhaps you only want it to be just:
$(elDebug.find('input.category-checkbox')[0]).prop('checked', true);

Resources