angularJS : disable link based on variable value, and display message box - javascript

I am struggling to figure out how to disable a ng-click event based on the value of a boolean variable.
I have a form, on which the user has to click a (+) sign/ link to add a new record, when the user does this, a small function is triggered, and sets a boolean to false.
Code:
vm.addNewRecord = function (formClass) {
vm.hasID = false;
};
The form has an icon/ link that allows the user to save information about participant, to the record.
Code:
<div class="icon">
<a ng-click="addParticipants(data)">
<i class="fa fa-fw fa-plus"></i>
</a>
</div>
That issue is that this information depends on a record id, but this id does not exist yet.
I need to be able to disable the ng-click of: addParticipants(data) is the value of hasId = false, and at the same time (somehow) allow the user to click it to display a message in the lines of: "Please save this record before adding participants."
What I have tried so far, and without success:
<div class="datagrid-icon">
<a ng-click="datagrid.add(datagrid)" ng-disabled="!hasID">
<i class="fa fa-fw fa-plus"></i>
</a>
</div>
And:
<div class="datagrid-icon">
<a ng-click="datagrid.add(datagrid)" ng-class="{'disabled': !hasID}">>
<i class="fa fa-fw fa-plus"></i>
</a>
</div>
I checked the value of hasID and it is false but I am still able to click on the (+) sign for addParticipants. And also, I am not sure how if I manage to disable the click, I am going to display the message instructing the user to first save the main record and then adding participants will be possible.
If anyone could offer some help to resolve this, that would be much appreciated.
Thank you.

To disable a link you can do like
<a ng-click="hasID && datagrid.add(datagrid)">
<i class="fa fa-fw fa-plus"></i>
</a>
But it's much better to have a method inside your controller like
vm.addToGrid = function(id) {
if (id) {
$scope.datagrid.add(id);
} else {
alert('Save the record before');
}
}
<a ng-click="vm.addToGrid(datagrid)">
<i class="fa fa-fw fa-plus"></i>
</a>

Related

Link within a bootstrap list-group-item, but popup confirmation before clicking link

I have a 'bootstrap list group item'. I am trying to create a link inside the link area. The code below works:
// THIS CODE WORKS //
<a href="" class="list-group-item list-group-item-action active text-white rounded-0">
// --- JUST A BUNCH OF HTML COMES HERE -- //
<i class="fa fa-trash" aria-hidden="true" onclick="window.open('?delete=<?=$x?>','_self');return false;"></i>
</a>
Now what I would like to do is to add a confirmation to this so the user doesn't delete by mistake.
// WANT TO ADD THIS FEATURE //
return confirm('Are you sure you want to delete?');
How would I combine these to? When I try they will not execute. I have tried.
// WHAT I TRIED //
function Heya()
{
return confirm('Are you sure you want to delete?');
}
function Hoo()
{
window.open('?delete','_self');return false;
}
// AND ON THE PAGE //
<i class="fa fa-trash" aria-hidden="true" onclick="Heya(); Hoo();"></i>
It doesn't work... And I also need a way to pass on the variable 'x' to the script since it will differ..
Thanks a lot for help.
function checkDelete(x)
{
if (confirm('Are you sure you want to archive?')) {
var url = '?delete=' + x;
window.open(url,'_self');
}
return false;
}
<i class="fa fa-trash" aria-hidden="true" onclick="return checkDelete(<?=x?>);"></i>

Is it possible to return something to a function from appended HTML?

Is it possible to return something to a function from appended HTML?
In my case, something that determines what button was pressed in that HTML.
Scenario
I am making a file menu system for web storage. You have other storage, bitmapr web storage, and then local disk. I want to be able to create a file selection system using jQuery. (e.g: I click select on bitmapr web storage, and then the function that called that returns that I clicked bitmapr web storage. (or an rational value that means that.)
Problem
I'm not sure how to tackle this scenario. I've tried using onclick returns, that doesn't work, and jquery append doesn't return what happens on onclick.
Is there a way to solve the scenario posted above?
Program code
Modal display function
var advancedModal = function(html, title, msg, color) {
$("body").append(`
<div class="w3-modal-content w3-animate-opacity w3-display-middle modal">
<header class="w3-container w3-${color}">
<span onclick="$(this).parent().parent().remove()" class="w3-button w3-display-topright">×</span>
<h2>${title}</h2>
<small>${msg}</small>
</header>
${html}
<footer class="w3-container w3-${color}">
<p>bitmapr</p>
</footer>
</div>
</div>`);
return (something determining what button was pressed)
};
advancedModal call
advancedModal(`
<div class="w3-container w3-animate-opacity">
<ul class="w3-ul">
<li class="w3-light-grey w3-animate-opacity" onclick="$('ul', this).toggle();">
<i class="fa fa-question"> </i><i class="fa fa-chevron-right"></i> Web Storage
<button class="w3-button w3-red" onclick="resetStorage()">Delete All</button>
<ul class="w3-ul">
${otherStorageHTML}
</ul>
</li>
<li class="w3-blue blueGradient w3-animate-opacity" onclick="$('ul', this).toggle();">
<i class="fa fa-images"> </i><i class="fa fa-chevron-right"></i> <b>bitmapr</b> Web Storage
<button class="w3-button w3-teal" onclick="return 'clicked me'">Select</button>
<ul class="w3-ul">
${bitmaprHTML}
</ul>
</li>
<li class="w3-blue w3-deep-purple w3-animate-opacity" onclick="$('ul', this).toggle();">
<i class="fa fa-archive"> </i><i class="fa fa-chevron-right"></i> Local Disk Storage
<button class="w3-button w3-teal" onclick="">Select</button>
<ul class="w3-ul">
Not Available Now
</ul>
</li>
</ul>
</div>
`, "Open", spaceLeft + "MB remaining in virtual storage", "blue"));
Notice: All of the ${} variables are defined correctly.
Text diagram
var value = advancedModal(...)
advancedModal(html, title, etc...) {
prints out html, but on click of a button, return a value corresponding to the button
}
Visual diagram
Extra thing
Before flagging/closing, please post in comments what your questions are or what you want cleared up. I tried hard to explain it all here but there may be something I am missing. Thanks.
Instead of returning a value, you can pass a callback. This can be a new parameter.
var advancedModal = function(html, title, msg, color,callback) {};
Now you can use a delegated method to call on when a button is clicked.
var advancedModal = function(html, title, msg, color,callback) {
... appending ...
$('.w3-container').on("click","button",callback);
};
This will call the callback function on any button that is clicked. Here is an example:
advancedModal(html, title, msg, color,function(){
console.log(this); // <-- this is the button
});
It will be a good idea to give the button tag an attribute that allows you to identify it.
Working Example: JsFiddle

jquery to match <p> values based on a given value

I have a grid of staff in divs on a page and within each div i have added a new 'filter-content' div which contains the ids of various criteria that apply to this member of staff. Such as 'specialisms', 'region', 'joblevel' etc.
Here is my mark up:
foreach (SearchFirmRecruiter searchFirmRecruiter in Model.OrderBy(o => o.LastName))
{
bool blnUserDeactivated = searchFirmRecruiter.DateRemoved.HasValue;
string strCipher = #searchFirmRecruiter.getSearchFirmRecruiterCipherId();
<div class="col-md-4">
<div class="panel panel-default text-center #(blnUserDeactivated ? "deactivated" : "")">
<div class="panel-body">
<i class="fa fa-user-circle-o fa-3x"></i>
<p class="h4"><b>#searchFirmRecruiter.FirstName #searchFirmRecruiter.LastName</b></p>
<div class="filter-content">
<p class="specialisms"><b>#searchFirmRecruiter.Specialism</b></p>
<p class="regions"><b>#searchFirmRecruiter.Regions</b></p>
<p class="supplierType"><b>#searchFirmRecruiter.SupplierType</b></p>
<p class="jobLevel"><b>#searchFirmRecruiter.JobLevel</b></p>
</div>
<p>#searchFirmRecruiter.Email</p>
#if (blnUserDeactivated)
{
//Set the value
blnShowDisabledRecruitersLink = true;
<a data-href="#Url.Content("~")SearchFirm/ActivateRecruiter/#searchFirmRecruiter.getSearchFirmRecruiterCipherId()" data-toggle="confirmation" data-btn-ok-icon="fa fa-check" data-btn-cancel-icon="fa fa-remove" data-container="body" data-placement="top" class="btn btn-sm btn-success"><i class="fa fa-check margin-right-spacing"></i>Enable</a>
}
else
{
<i class="fa fa-pencil margin-right-spacing"></i>Edit
<span data-toggle="tooltip" data-placement="bottom" data-container="body" data-trigger="hover" title="" data-original-title="This user will no longer be able to access their jobs and submit any candidates"><a data-href="#Url.Content("~")SearchFirm/DeactivateRecruiter/#strCipher" data-toggle="confirmation" data-btn-ok-icon="fa fa-check" data-btn-cancel-icon="fa fa-remove" data-placement="top" class="btn btn-sm btn-danger"><i class="fa fa-remove margin-right-spacing"></i>Disable</a></span>
}
</div>
</div>
</div>
}
On the page the filter-content div looks like this:
,19,17,25,
,6,9,12,16,19,
,1,
,1,2,4,
Down the left hand side of the page i have some filter options, one for each of the classes above. So these will list all the 'specialisms', 'regions' etc as checkboxes. When a filter checkbox is selected i am running a javascript function to filter for that filter type. So, for example, if a user selects the 'Accountancy' specialism and that is id 25. I want to only show the members of staff that have that 'Accountancy' specialism.
As the filters are clicked so the members of staff will be shown if they meet the criteria.
I am completely new to JQuery but i'm pretty sure this is the best way to achieve what i want.
I have a javascript function for each filter which passes in the selected filter value, within this funtion, ideally, i want to firstly hide all the divs and then show only the ones that match the filter criteria. At the moment i am just playing around with trying to return the specialisms, once i have those i can do some logic to determine if the passed in specialismId is contained and therefore whether this member of staff should be shown or not
function filterSpecialism(specialismId) {
alert(specialismId);
alert($(".filter-content").find('p').find('specialisms').val)
}
Here is an image of how the page currently looks, so within this example Accountancy is selected as the filter, this is specialism id 25 so only James Dibner and Harjinder Royston should be shown
example
I hope that all make sense and i appreciate any answers or suggestions. Many thanks all

TimeOut While waiting for element with locator

I am trying to test below code:
<div name="userElem" *ngFor="let user of users ; let i=index">
<div class="list-group-item" id="user-{{i}}" (click)='selectUser(user)' [style.backgroundColor]="user?._id==selectedUser?._id ? '#F0F0EE' : 'white'">
<div *ngIf="user?._id==selectedUser?._id">
<div class="pull-right">
<a id="delete-user-{{i}}" (click)="deleteUser(user._id)">
<i class="fa fa-trash fa-fw"></i>
</a>
<a (click)="editUser(user._id)">
<i class="fa fa-pencil fa-fw"></i>
</a>
<a [routerLink]="['/edit',user._id]" name="userLink-{{i}}">
<i class="fa fa-eye fa-fw"></i>
</a>
</div>
</div>
</div>
</div>
By Using Below E2E Test Case:
it('should delete a user', () => {
page.navigateToUserComponent();
let selectUserElem = element(by.id('user-0')).click(); //this event is fired as I can see user getting selected.
let deleteUserElem = element(by.id('delete-user-0'));
browser.wait(function() {
return browser.isElementPresent(by.id('delete-user-0'));
}, 5000);
expect(deleteUserElem.isPresent()).toBeTruthy(); // if element is present I want to click that element .i.e. delete the first user in array
});
But So Far Not Getting Any Success.
I tried Multiple Approaches as discussed in this link:
StackOverflow Post
But Couldn't make it work.
any help?
Thanks
If you want to identify first delete_user element you can use following xpath.
let deleteUserElem = element.all(by.xpath(".//a[contains(#id, 'delete-user-')]")).first();
then you can cobine it with the protractor expected condition to wait till the desired web element is present.
EC = protractor.ExpectedConditions;
browser.wait(EC.presenceOf(deleteUserElem),20000, 'element is not visible within the time specified');
Use ExpectedConditions along with browser.wait() to make your script wait for certain condition:
var EC = protractor.ExpectedConditions;
var elm = element(by.id('delete-user-0'));
browser.wait(EC.presenceOf(elm), 5000);
Are you using socket.io? There seems to be bug where protractor does not work if you are using socket.io in your app: https://github.com/angular/angular/issues/11853 .

Angular, how to set class to the clicked list item and remove from others li items?

I have this list where I'm trying to set class to the clicked list item (but class should be set only for clicked item).
I tried to do by this way but without luck:
<a href=""
ng-ctrl="ThemesCtrl"
ng-click="checkThemeContent(theme);"
ng-repeat="theme in themes"
ng-hide="theme[filterProp] !== filterValue"
class="list-group-item">
<b>{{theme.name}}</b>
<span class="themesListIcons">
<i class="fa fa-check-square-o"></i> {{theme.avg_score}}
<i class="fa fa-comment-o"></i> {{theme.count_of_cards}}
</span>
</a>
How can i do it please in the right way?
Thanks for any help.
Great.
Sorry because I have not plunker account, so I must explain you on theoretical way.
George, you have to create function in controller that selects your item, for an example, in your case:
$scope.checkThemeContent = function (name) {
$scope.selectedName = name;
}
After this step, you must only call this function in your HTML like this:
<a href=""
ng-class="{selected:theme.name==selectedName}"
ng-click="checkThemeContent(theme.name)"
ng-repeat="theme in themes"
class="list-group-item">
<b>{{theme.name}}</b>
<span class="themesListIcons">
<i class="fa fa-check-square-o"></i> {{theme.avg_score}}
<i class="fa fa-comment-o"></i> {{theme.count_of_cards}}
</span>
</a>
Please take look on ng-click part. You have to pass some property ('theme.name') of item (in your case 'theme') from list ('themes'), because you can't compare objects.
In ng-class you must also pass the same property as in ng-click.
Hope it helps.
you need change the syntax ng-class directive
<a href=""
ng-class="{'selected':$index==selectedIndex}"
ng-ctrl="ThemesCtrl"
ng-click="checkThemeContent(theme);currentTheme=theme"
ng-repeat="theme in themes"
ng-hide="theme[filterProp] !== filterValue"
class="list-group-item">
<b>{{theme.name}}</b>
<span class="themesListIcons">
<i class="fa fa-check-square-o"></i> {{theme.avg_score}}
<i class="fa fa-comment-o"></i> {{theme.count_of_cards}}
</span>
</a>
If the 'selectedIndex' is your scope variable that represents your selected item in the controller and the 'selected' is your CSS class, try to change the ng-class part like this:
ng-class="{selected: $index==selectedIndex}"

Categories