searching json file for key angular 2+ - json

On my website I would like to verify the input a user does when he puts in the 3 letter code or 2 letter code. It should return the value of the key.
So if he types in "BTC" it should return "bitcoin" and show it next to the input.
I found this example, but it seems quite complicated for what I want: https://github.com/ghiden/angucomplete-alt and it is angularjs
Search three lettercode coin: <input ng-model="query">
{
"42": "42 Coin",
"365": "365Coin",
"404": "404Coin",
"611": "SixEleven",
"808": "808"
}

The easiest way is to probably do this:
- Check form input on each type
oninput="checkInput($event)"
Then you can see if it matches any of the keys:
function outputData(value) {
alert(value);
}
function checkInput(event) {
// Check event.target.value with either if cases or a switch statement and
//then trigger the function that outputs the key value.
if (event.target.value === 'BTC') {
outputData('Bitcon');
} else if (event.target.value === '....') {
.....
}
}

Related

Is it possible to only give one argument to function with two parameters?

I have kinda a wierd question. I'm working on removing redundance from my code, and I have two functions which are basically the same, except one of the functions have two parameters and the other one only have one.
I'm wondering if it's possible to "skip" one of the parameters when the function is called, in order to reduce redundance? The functions in this case is in VueJS. Here are the functions:
addTask: function (task, member) {
if (task === '' || member === '') {
alert ('Enter Task & Member!')
}
},
addMember: function (addTeamMember) {
if (addTeamMember === '') {
alert ('Enter Name Of Team Member')
}
So in other words, is it possible to call "addTask" and only parse one argument and skip the other?
You can do it by declaring the variable directly as you can do it in many other languages.
For example:
function addTask(task, member = "") {
}

React JS: Ensure Progratimacally created input fields are unique from each other

I'm creating a form to seed a varying number of teams to a tournament, by first mapping them to a form group with labels and number input. How can I make it so each field has to be unique before the form is considered valid?
By unique, I mean each field with take a certain number in a range, say if a tournament has 14 teams, then each field should be a number between 1 and 14, but two fields shouldn't be able to take the same number.
renderButton() {
return (
<Form onSubmit={this.handleSeedingSubmit}>
{this.state.teams.map((team)=>
<FormGroup key={team.name}>
<Form.Label >{team.name}</Form.Label>
<Form.Control type = "number" name={team.name} min={1} max={this.state.tournament.noTeams} onChange={this.onChangeHandler} required />
</FormGroup>
)}
<Button type="submit" >
Submit
</Button>
</Form>
);
}
On submit each team is being mapped with {name, seeding}. I want every team to have a unique seeding as they will be sorted into pools based on seeding later.
Well what you can do is make the number inputs controlled by storing their values in the store:
state = {
// other state,
inputs: {}
}
then in onChangeHandler set the value of each input in the state:
function onChangeHandler(e) {
const { name, value } = e.target;
this.setState({
inputs: {
...this.state.inputs,
[name]: value
}
})
}
then when your form is submitted you can add a check to see if the values are unique or not, there are many ways to do that, what I'm doing here is remove the duplicates from the array and then check the length of the array against the values in the state like this:
function handleSeedingSubmit(e) {
e.preventDefault();
const { inputs } = this.state;
const valuesInState = Object.values(input);
const uniqueValuesArr = [...new Set(valuesInState)];
const areInputsValid = valuesInState.length === uniqueValuesArr.length;
if (!areInputsValid) {
// set Error here
return;
}
// Hurray!! Inputs are valid
// Handle Success case here
}
Hope it helps :)

Qtableview, add widgets between rows

I have a QTableview (multiple columns, sorting) and would like to add a button that shows additional data below the current row. For the rendering of this additional data I would like to use another widget, that fills up a variable height and spans all the rows.
While I know that I can create delegates for cells, I was wondering if this is possible for rows or whether that would mean that I would have to inherit from a tableview and modify its paint method, which seems to be lot of work for a novice like me.
QVariant YourTableModel::data(const QModelIndex & index, int32_t role) const
{
if (!index.isValid()) {
return QVariant();
}
if (role == Qt::DisplayRole || role == Qt::EditRole)
{
switch (index.column())
{
case YOUR_COL:
double theDouble = getDoubleFromModelSomewhere();
return QString::number(theDouble, 'f', 3); // Format shows 3 decimals
}
}
return QVariant();
}
If I have understood your question properly then I think this is the answer.
QTableView *view = new QTableView;
view->setItemDelegateForRow(int row, QAbstractItemDelegate *delegate);

How to filter or custom filter array of objects based on matching values from another object

I implemented an advance search with 15 input fields in AngularJS.
In the page load itself the result set is return from database in JSON format and i need to do the filter in client side only.
The input criteria's equivalent column is available in the result set and i need to check in its respective column only.
I am converting each column by JSON.stringify() and check with the search params like the below :
$scope.filteredData = $scope.actualData.filter(function(item) {
return JSON.stringify(item.FirstName).toLowerCase().indexOf(lowerFirstName) != -1 &&
JSON.stringify(item.LastName).toLowerCase().indexOf(lowerLastName) != -1 &&
JSON.stringify(item.EmailAddress).toLowerCase().indexOf(lowerEmailAddress) != -1 &&
JSON.stringify(item.Address1).toLowerCase().indexOf(lowerAddress1) != -1 &&
JSON.stringify(item.Address2).toLowerCase().indexOf(lowerAddress2) != -1;
...... etc // upto 15 fields
});
Since i have the 15 input fields and the actual result set contains a minimum of 50,000 records.
So converting each record's each column by JSON.stringify() and check with search params will surely cause the performance issue.
Is there any other way to achieve the filtering in client side with other approach.
I posted a sample code in Plunker with 5 input fields only : http://plnkr.co/edit/nUWZEbGvz7HG6gb91YZP
sylwester's answer is the normal way you'd filter things. Your code looks like you want to filter down to only the object that matches every input field. You code attempts to find an object where every property matches the searchParams object. At that point, I don't see what benefit there is to finding that object, because the user already created the object again! Nonetheless, here's a proper version of your code:
Live demo here.
<div ng-repeat="data in actualData | filter:searchData()">
$scope.searchData = function() {
return function(item) {
return Object.keys(item).every(function(key) {
// skip the $$hashKey property Angular adds to objects
if (key === '$$hashKey') { return true; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
return item[key].toLowerCase() === $scope.searchParams[searchKey].toLowerCase();
});
};
};
You really need to limit the data coming from the server for the browser's sake and for the server's sake. It's easy to implement a LIMIT, OFFSET system. It sounds like, overall, you just need to be able to query the server for a certain record.
From your comments, it seems you definitely want Angular's built in filter filter:searchParams, and just capitalize your searchParams models to match your data. For fun, I'll include more options for finer tuning.
This one almost mimics filter:searchParams. You can change > 1 to adjust when the partial matching kicks in, or have it return true only when both items are strictly equal === to disable partial matching. The difference here is that all items are hidden until matched, whereas filter:searchParams will show all items and then remove what doesn't match.
Live demo here.
$scope.searchData = function() {
return function(item) {
return Object.keys(item).some(function(key) {
if (key === '$$hashKey') { return false; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
var currentVal = $scope.searchParams[searchKey].toLowerCase();
var match = item[key].toLowerCase().match(currentVal);
return currentVal.length > 1 && match;
});
};
};
Lastly, to perfectly mimic filter:searchParams, you'd just put in a check to NOT filter the items until there is user input and the input is long enough to start the partial match.
Live demo here.
$scope.searchData = function() {
var partialMatchLength = 2;
return function(item) {
var shouldFilter = Object.keys($scope.searchParams).some(function(key) {
return $scope.searchParams[key] && $scope.searchParams[key].length >= partialMatchLength;
});
if (!shouldFilter) { return true; }
return Object.keys(item).some(function(key) {
if (key === '$$hashKey') { return false; }
var searchKey = key.charAt(0).toLowerCase()+key.slice(1);
var currentVal = $scope.searchParams[searchKey].toLowerCase();
var match = item[key].toLowerCase().match(currentVal);
return currentVal.length >= partialMatchLength && match;
});
};
};
First of all you ng-repeter with 50.000 records more likely is going to kill your browser, so you should thing about pagination.
Secondly you can easy filter your data using angular filter please see that demo
http://plnkr.co/edit/R8b8G4xCMSQmX1144UJG?p=preview
<div ng-controller="ListCtrl">
<br />
First Name:
<input type="text" id="txtFirstname" ng-model="searchParams.FirstName">
<br/>Last Name:
<input type="text" id="txtLastname" ng-model="searchParams.LastName">
<br/>Email Address:
<input type="text" id="txtEmailAddress" ng-model="searchParams.EmailAddress">
<br/>Address 1:
<input type="text" id="txtAddress1" ng-model="searchParams.Address1">
<br/>Address 2:
<input type="text" id="txtAddress2" ng-model="searchParams.Address2">
<br/>
<button class="btn btn-primary" ng-click="searchData()">Search</button>
<br />
<hr />
<b>Filtered Data(s):</b>
<div ng-repeat="data in actualData | filter:searchParams ">
<span ng-bind="data.FirstName"></span>
<span ng-bind="data.LastName"></span> |
Address : {{data.Address1}}
</div>
<hr />
</div>

Detecting first and last item inside a Groovy each{} closure

I am using Groovy's handy MarkupBuilder to build an HTML page from various source data.
One thing I am struggling to do nicely is build an HTML table and apply different style classes to the first and last rows. This is probably best illustrated with an example...
table() {
thead() {
tr(){
th('class':'l name', 'name')
th('class':'type', 'type')
th('description')
}
}
tbody() {
// Add a row to the table for each item in myList
myList.each {
tr('class' : '????????') {
td('class':'l name', it.name)
td('class':'type', it.type)
td(it.description)
}
}
}
}
In the <tbody> section, I would like to set the class of the <tr> element to be something different depending whether the current item in myList is the first or the last item.
Is there a nice Groovy-ified way to do this without resorting to something manual to check item indexes against the list size using something like eachWithIndex{}?
You could use
if(it == myList.first()) {
// First element
}
if(it == myList.last()) {
// Last element
}
The answer provided by sbglasius may lead to incorrect result like when the list contains redundants elements so an element from inside the list may equals the last one.
I'm not sure if sbglasius could use is() instead of == but a correct answer could be :
myList.eachWithIndex{ elt, i ->
if(i == 0) {
// First element
}
if(i == myList.size()-1) {
// Last element
}
}
if (it.after.value != null) {
......
}
Works for maps