Ext JS - Can I 'chain' methods on a field? - extjs

HI,
I am just trying to set a field value and disable it at the same time.
Can this be done in ext js? The docs are very weak on this subject.
something like this generates errors:
myForm.getForm().findField('start_date').setValue('').setDisabled(true);
I'm used to JQuery which does this sort of thing nicely but haven't had luck with Ext.
Thanks for any help.

Actually, Field.setValue does in fact return a reference to the field (docs), so you should be able to call setDisabled (inherited from Component) as you have it. You must have some other issue going on. Maybe findField('start_date') is returning null. You have to make sure all the return values are what you expect. Use Firebug to figure out the error, or break apart your statement and see which call is actually failing.
Anything is "chainable" as long as the return value is the object itself (usually denoted as this in the docs). In jQuery, everything operates on DOM elements, so it is consistent. In Ext, you have lots of components with various behaviors. Sometimes chaining makes sense, sometimes it does not -- just make sure you check the docs when you aren't sure.

i agree with bmoeskau it should work if the field is there and found by the form. I would advise you to to it something like that to prevent errors:
var field = myForm.getForm().findField('xyz');
if(field !== undefined)
{
field.setValue('');
field.setDisabled(true);
}
else
{
// Error Handling
}

This is because setValue() method doesn't return field object. You cannot use setDisabled() in such way.
EDIT: (For those down-voting morons)
From ExtJS documentation:
method: setValue(value)
Parameters:
value : Mixed
The value to set
Returns:
void

Related

How to access mongoose populated fields?

I'm not able to access the populated fields of mongoose objects. I want to output it in my page.
Example:
"console.log(booking.assignedUser.first)" gives me back:
TypeError: Cannot read properties of undefined (reading 'first')
But from what I can tell, this should be working. The field is clearly there.
In my jsx file:
console.log(booking.assignedUser)
Object:
{
etc etc
assignedUser: { _id: new ObjectId("62f068b068802d58c8d35442"), first: 'driver' },
etc etc
}
So why I can access booking.assignedUser and it shows me the data, but booking.assignedUser.first doesn't work?
Because these values are being populated from the DB, I guess they aren't loading fast enough so it's giving me this error.
If I check to make sure the value exists first, then use it, it's working.
I'm working with a lot of this type of data in my app, so instead of outputting the jsx directly in the react object, I'm using a function to return it all for me which I pass in the db data.
using a ternary at the beginning of the output within the React component was not good enough, for example.
{ data ?
<Form>
<SomeStuffHere>
<SomeMoreStuffHere>
<Form.Control> {data.something} </Form.Control>
</Form>
: '' }
This was not good enough. It would still error out. I had to place the ternary immediately on the field in order for it to work.
Doing this for every single field would be a pain in the ass, so putting it into a function first seems to work better.
Probably , you are trying to achieve data's populates when data didn't set yet. Need to be sure data is set already.
You can use it like ;
booking.assignedUser && console.log(booking.assignedUser.first)
If the page can't view components due to data is empty, need to use this condition beginning of view component.
data.length > 0 && ...</Component/>

Lightning Web Component Specialist Super badge: Challenge 7

I am having trouble solving the Challenge 7 I have the required imports as well as required functions in the JS file. Still #Trailhead giving error:
We can’t find the getLocationFromBrowser() function in the component boatsNearMe controller. Make sure the component was created according to the requirements, including the use of 'getCurrentPosition()' to get the navigator’s geolocation, the arrow notation with 'position =>', getting the coordinates from the position, and assigning them to the controller’s properties 'latitude' and 'longitude, using the proper case sensitivity.
---- Removed the CODE Section in order to stay with Trailhead's Policy ----
I guess this is something which i am missing out in the code.
Your references to the Geolocation Latititude and Longitudes are missing an "_"
You have them like this (single underscores);
rowBoat.Geolocation_Latitude_s
And this need to be like this (double underscores);
rowBoat.Geolocation__Latitude__s
I haven't gone through all the code, but at least these look wrong in your code.
Also, not sure that the #track is explicitly needed in this case (anymore).
The verification code is extremely picky. If you remove the parentheses around the word position, I think it will work.
You can try 2 changes to pass the challenge,
remove the parentheses around position from the callback function of getCurrentPosition
follow below steps to rectify mapMarkers creation code
The data that is passed to the createMapMarkers is of below format,
'[{"attributes":{"type":"Boat__c","url":"/services/data/v48.0/sobjects/Boat__c/a022w000006RA28AAG"},"Name":"Sanya","Geolocation__Latitude__s":24.8513290,"Geolocation__Longitude__s":119.4862410,"Id":"a022w000006RA28AAG"},{"attributes":{"type":"Boat__c","url":"/services/data/v48.0/sobjects/Boat__c/a022w000006RA2DAAW"},"Name":"Longxue","Geolocation__Latitude__s":22.6216820,"Geolocation__Longitude__s":113.7630620,"Id":"a022w000006RA2DAAW"}]'
So, you may parse it using JSON.parse(boatData) and then call the map() function on it,
this.mapMarkers = JSON.parse(boatData).map((rowBoat) => {
return {
location: {
Latitude: rowBoat.Geolocation__Latitude__s,
Longitude: rowBoat.Geolocation__Longitude__s
},
title: rowBoat.Name
};
});
And definitely use double underscore to access Latitude and Longitude from Geolocation as shown above.
One more point, set the isLoading to true just before creating the mapMarkers and set it to false after it is created within the createMapMarkers method.
Hope this will work for you :)

TyperError: Cannot read property 'length' of undefined

Our team is using angularjs to develop a ServiceNow widget and we are seeing "TyperError: Cannot read property 'length' of undefined" in our console:
When we click on "at eval", it takes us to this particular snippet of code with line 321 highlighted:
We can't seem to figure out what's causing that error. We are using $watch on an array ($scope.data.list) and have read that $watchCollection might be better, but we tried that with no change. Any ideas what could be causing this error and how to get rid of it?
From the code you have posted, you haven't defined or nor declared
$scope.data.list (I'm assuming $scope.data is defined somewhere). To
resolve that, you need to at least declare your $scope.data.list first to watch over it.
Coming to the $watch part, it depends on what your requirement is.
$scope.$watchCollection looks for changes made in the array as well as elements whereas,
$scope.$watch will only look for changes made if the array is totally
assigned to a different one. Otherwise, if you want to watch deep, you can
use $scope.$watch with a boolean true variable passed as a third
argument to it.
Refer this link for the full documentation - https://www.sitepoint.com/mastering-watch-angularjs/
As of my knowledge $watch on $scope.data.list called whenever any value changed in this collection
So by looking at error it seems like $scope.data.list list in no longer exits in $scope.data. Try to find out where $scope.data is going to change.
And use below syntax for watch on collection
$scope.$watchCollection('names', function(newList,oldList) {
if(newList && newList.length) {
$scope.data.list = newList.length;
}
});

Can't find id of Angular ui-grid element with Selenium/Protractor

I have some Protractor tests that are running on an Angular application that uses ui-grid. I have some working smoke tests for the application, but I am just starting to implement tests using https://github.com/angular-ui/ui-grid/blob/master/test/e2e/gridTestUtils.spec.js to test the ui-grid components. The problem I'm having is that I need the actual id of the grid element in order to use the getGrid function.
I'm able to successfully locate the element using element(by.css("[id$='-grid-container']")), but for some reasons my attempts to get the full id out of the element have failed. Here is what I am trying:
var grid = element(by.css("[id$='-grid-container']"));
grid.getAttribute('id').then(function(result) {
console.log(result);
var myGrid = gridTestUtils.getGrid(result.toString());
gridTestUtils.expectCellValueMatch(myGrid, 0, 0, 'Cox');
});
The console.log(result); is not logging anything. It doesn't SEEM necessarily related to ui-grid, it's just Selenium isn't finding the id for some reason. As far as I can tell I'm using getAttribute correctly; it works with this syntax in other tests, but maybe I'm missing something. Any ideas why this isn't working?
Edit because my comment is unreadable:
Thanks for the suggestions. However, I'm still just as confused because
var grid = element(by.css("[id$='-grid-container']"));
console.log(grid.toString());
grid.getAttribute('id').then(function(result) {
console.log('======'+result);
var myGrid = gridTestUtils.getGrid(result.toString());
gridTestUtils.expectCellValueMatch(myGrid, 0, 0, 'Cox');
});
gives a console output of
[object Object]
======
so it seems like the element is being found, which I had already checked, and the console.log inside the promise is being executed.
It's like it can't find the 'id', which according to the API documentation means there is no id on the element. But that is definitely not true.
Not sure on the semantics, but you could try this, just to make sure that you are getting the first element, if multiple:
element.all(by.css('[id$="-grid-container"]')).first().getAttribute('id').then(function(result) {
console.log(result);
var myGrid = gridTestUtils.getGrid(result.toString());
gridTestUtils.expectCellValueMatch(myGrid, 0, 0, 'Cox');
});
Your code looks correct.
However, if your console.log(result) doesn't log anything, this means you either didn't find the element or the moment you execute the getAttribute() the element is no longer present.
See in the API description, that getAttribute() always returns a value, if the element is present.
Maybe try to extend console.log('======='+result); to figure out, if that line of code gets executed (I'm pretty sure it's not executed). Also try console.log(grid.toString());, which should output [object Object], if the element is really found.
As for the ElementFinder, I'm used to use the ' and " just the other way around, so element(by.css('[id$="-grid-container"]')); or shorter $('[id$="-grid-container"]').
Let me know, if this helped and you could further determine the cause.
Round 2
Let's exclude a few things
change getAttribute('id') to getAttribute('outerHTML') to see,
if there is anything logged.
change (result) to (resultattr) to exclude, that result is else used by a plugin, who put result as a global variable.
change grid.getAttribute() to be element(by.css("[id$='-grid-container']")).getAttribute
What are the results of those actions?

AngularJS typeahead select on blur

I'm using typeahead through in my AngularJS project and I would like to have it select the entry if I type the full value and click out of the field.
I've put together an example of what I mean
http://plnkr.co/edit/NI4DZSXofZWdQvz0Y0z0?p=preview
<input class='typeahead' type="text" sf-typeahead options="exampleOptions" datasets="numbersDataset" ng-model="selectedNumber">
If I type in 'two' and click on 'two' from the drop down then I get the full object {id: 2, name: 'two'}. This is good, if however I type 'two' and click to the next field without selecting is there a way to accept the top of the list on loss of focus on a text field?
I'm not sure if I'd want to have that sort of functionality in my app. The user hasn't actually selected anything. So selecting something for them would introduce frustrations.
But I do understand that often odd requirements are needed. In this case, I'd attack it using ngBlur. Assign a function to be called on blur. You can grab the contents of ng-model and then loop through your data (assuming static & not being sent via server) to find a match.
You can most likely just look at the source code of your typeahead directive and strip out the part does the comparison and then choose the first item in the array.
Unfortunately the underlying component does not emit any events for this condition. This will make the solution more complex. However when the value is being entered and the Typehead magic has happened you can supplement those events and catch them to update your ngModel.
I have created a plnkr based on your plnkr and although have not cleaned up but it is a working plnkr doing by far what you need.
The gist of this is following code however you can put this code wherever best suited
The explanation below:
//Crux - this gets you the Typeahead object
var typeahead = element.data('ttTypeahead');
//This gets you the first
var datum = typeahead.dropdown.getDatumForTopSuggestion();
if (datum){
//you can do lot of things here however
//..I tried to - fill in the functionality best suited to be provided by Typeahead
//for your use case. In future if Typeahead gets this
//..feature you could remove this code
typeahead.eventBus.trigger("hasselections", datum.raw, datum.datasetName);
}
In the above code you can also save the datum somewhere in the scope for doing whatever you like with it later. This is essentially your object {num: 'Six'} Then you may also use ngBlur to set it somewhere (however the plnkr I created doe snot need these gimmicks.)
Then further down - ngModel's value is set as below
element.bind('typeahead:hasselections', function(object, suggestion, dataset) {
$timeout(function(){
ngModel.$setViewValue(suggestion);
}, 1);
//scope.$emit('typeahead:hasselections', suggestion, dataset);
});
I'm with EnigmaRM in that ngBlur seems to be the way to do what you want. However, I agree with the others that this could be somewhat strange for the end users. My implementation is below (and in plnkr). Note that I trigger on ngBlur, but only apply the model if and only if there is only one match from Bloodhound and the match is exact. I think this is probably the best of both worlds, and hope it should give you enough to go on.
$scope.validateValue = function() {
typedValue = $scope.selectedNumber;
if(typedValue.num !== undefined && typedValue.num !== null)
{
return;
}
numbers.get(typedValue, function(suggestions) {
if(suggestions.length == 1 && suggestions[0].num === typedValue) {
$scope.selectedNumber = suggestions[0];
}
});
};

Resources