Change view depending on click in Angular2 - javascript

How can I change the view in my Angular2 template:
<td *ngIf="hour === first">{{obj[0].from}}</td>
<td *ngIf="hour === second">{{obj[1].from}}</td>
<td *ngIf="hour === third">{{obj[2].from}}</td>
This td is a part of bigger table, but you'll get the logic.
Now I have another part of template below:
<div class="info">
<p>{{schedule[0].name}}</p>
<p>{{schedule[1].name}}</p>
<p>{{schedule[2].name}}</p>
</div>
I need to match the click on the first td so that only first p will be displayed in the .info class and others will not be visible, and so with the others: if second td is clicked, the second p should be displayed, other not, etc..
I've tried following this tutorial: http://jilles.me/ng-click-and-ng-if-in-angular2/ but couldn't get it to work. In my actual template there is more stuff besides the p, but I believe the logic should be the same.
How can I do this?
Thanks guys.

Firstly use ngFor for printing the p as follows:
<div class="info">
<p *ngFor="let s of schedule">{{s.name}}</p>
</div>
Secondly use index and add the hidden tag to the p as follows:
<div class="info">
<p *ngFor="let s of schedule; let i = index"
[hidden]="hiddenIndex === i">{{s.name}}</p>
</div>
Thirdly add click method on td which calls a function that sets the hiddenIndex value.
<td *ngIf="hour === first" (click)="setHiddenIndex(0)">{{obj[0].from}}</td>
<td *ngIf="hour === second" (click)="setHiddenIndex(1)">{{obj[1].from}}</td>
<td *ngIf="hour === third" (click)="setHiddenIndex(2)">{{obj[2].from}}</td>
in the class:
hiddenIndex: number;
setHiddenIndex(index: number) {
this.hiddenIndex = index;
}
That's it. My solution uses hidden instead of ngIf. We can't use ngIf and ngFor on one element so if you'd like to use ngIf you need to build your html a bit differently.

Related

Get div value from class name

I have a very large HTML that contains lots of divs with the same name, I want a way to only filter or extract that value from that div.
Here is an example:
<td class="last">
<div class="container-relative">
<div class="name" title=""User" <John Appleseed>"></div>
<div class="date">9/17/2019</div>
<div class="tool"></div>
</div>
</td>
I need to extract only what's between <John Appleseed>, in this case is 'John Appleseed'.
You could use querySelectorAll to take all the elements with class name, then get the title attribute with getAttribute, and finally use a regular expression to match text between <>.
document.querySelectorAll('.name').forEach(item => {
let title = item.getAttribute('title');
console.log(title.match(/\<.*\>/));
});
<td class="last">
<div class="container-relative">
<div class="name" title=""User" <John Appleseed>"></div>
<div class="date">9/17/2019</div>
<div class="tool"></div>
</div>
</td>
var divs=[];
for(i=0,j=0,obj=document.getElementsByClassName("name");i<obj.length;i++)
if(obj[i].title.includes("John Appleseed") &&
/* obj[i].title.split("\"")[2].trim()=="<John Appleseed>" && */
obj[i].tagName.toLowerCase()=="div"){
divs[j++]=obj[i];
}
console.log(divs);
separate your div using div ID. Then get your respective div using that value of ID. Then in javascript you can use getElementByID.
You can use Xpath,
.//div[contains(#class, 'Test')]
Then extract you required text from it.

cant get text from an element in jQuery

I have a HTML setup as follows and am trying to use jQuery to access the textin the font field. The table has multiple rows, hence the first line in the jQuery, for some reason I'm getting an empty string returned for the title variable. Thank you for your help!
HTML
<table class="table">
<tbody>
<tr>
<td class="head">
<a href="link" target="_self">
<p>
<font>SomeText</font>
</p>
</a>
</td>
</tr>
</tbody>
</table>
jQuery
$('.table').each(function(){
$(this).filter(function(){
var data = $(this);
title = data.children(".head").text();
json.array.push({
"title" : title
});
})
})
.head is not a child of .table. So .children(".head") will not return any elements. You should use .find instead.
Also, the .filter seems unnecessary:
$('.table').each(function(){
var data = $(this);
title = data.find(".head").text();
json.array.push({
"title" : title
});
})
Your element with class head has no text in it, you need to adjust your selector to get the actual font element, like this:
data.children(".head font").text();

How to disable a div and all elements inside div?

My problem is, I want to disable div. I ma not getting a way to do it.
<div ng-repeat="item in items">
<div ng-click="somefunction()">{{some value}}</div>
</div>
JS:
$scope.items = [1,2,3,4,5];
I want to disable all div having even value.
Divs cannot be disabled by HTML. You can do it by code:
<div ng-click="somefunction(item)">{{some value}}</div>
$scope.somefunction = function(item) {
if( item % 2 === 0 ) {
return;
}
// rest of logic as before
};
You cant disable div. but you can disable link or button like:
<div ng-repeat="item in items">
<a ng-click="somefunction()" ng-disabled="disabledEvenItems(item)">{{some value}}</a>
</div>
Or you can add style base on it:
<div ng-repeat="item in items">
<div ng-click="somefunction()" ng-class="{{'myClass': disabledEvenItems(item)}}">{{some value}}</div>
</div>
</div>
$scope.disabledEvenItems = function(item) {
return item % 2 !== 0
};
To run the function only for odd values you can use $even / $odd helper properties ngRepeat offers:
<div ng-repeat="item in items">
<div ng-click="$even && somefunction()">{{some value}}</div>
</div>
UPD.
Angular way of doing what you are after is to use expression like this:
<div ng-click="item % 2 && somefunction()">{{some value}}</div>
Try this :
remove onclick from div as shown below
<div ng-repeat="item in items" class="divList">
<div>{{some value}}</div>
</div>
use .filter() to find div with even values and detach click handler
$(function(){
$('.divList div').click(somefunction());
$('.divList div').filter(function(){
var value = parseInt($(this).text()) || 0;
return (value % 2 ==0);
}).off('click');
});
Use display:none
<div id="someId" style="display: none;">
visibility: hidden hides the element, but it still takes up space in the layout.
display: none removes the element completely from the document, it doesn't take up any space.

Selecting first child based on attributes

I wanna be able to select a specific set of child in which an attribute is defined.
But how to select childs which are first child of the root selector that having the attribute data-role
first-of-type selector doesn't work due to the type of the element.
Here we have a sample of the DOM.
<body>
<div data-role="ca:panel" title="foo">
<div data-role="ca:vbox" width="100%">
<div data-role="ca:form">
<div data-role="ca:formitem">
<div data-role="ca:hbox">
<input data-role="ca:textinput">
<div data-role="ca:menu"></div>
</div>
</div>
<div data-role="ca:formitem">
<input data-role="ca:passwordinput">
</div>
<div data-role="ca:formitem">
<select data-role="ca:combobox">
<option>[...]</option>
</select>
</div>
</div>
<table>
<tbody>
<tr>
<td>
<span data-role="ca:label"></span>
</td>
<td>
<button data-role="ca:button"></button>
</td>
<td>
<button data-role="ca:button"></button>
</td>
</tr>
</tbody>
</table>
</div>
</body>
My filter should select only
<div data-role="ca:form">
<span data-role="ca:label"></span>
<button data-role="ca:button"></button>
<button data-role="ca:button"></button>
It should work in any case, meanings, it shouldn't be linked to a specific structure of the dom and must use data-role as 'selector'.
I'm not a relevant jQuery developer. I tried some selector such as $('[data-role]:first-of-type'); but it doesn't work.
Do you have an idea to select the right set of child.
Note: Finding the first parent is not a concern.
It is possible to do this generically using a filter, so long as you have a start node:
JSFilter: http://jsfiddle.net/TrueBlueAussie/2uppww9s/5/
var root = $('[data-role="ca:vbox"]');
var matches = root.find('[data-role]').filter(function(){
return $(this).parentsUntil(root, '[data-role]').length == 0;
});
alert(matches.length);
You can use the :first pseudonym to select the first occurance of a element like for example:
var elm = $('*[data-role="ca:form"]:first');
this will select * any type of DOM-element, with the data-role that matches "ca:form"
Since you want to return two buttons with the same data-role, we cant use ":first" for that. You would have to get the first child of a that matches in that case
var elm = $('td').children('button[data-role="ca:button"]:first');
This will look through the child elements of all TD-tags and find the first button with data-role matching "ca:button"
If you want first of all overall specifications, then you can simply use selector on all three tag types and filter them as so:
$('div, span, button').filter(function(i){
if (this.tagName == 'DIV' && $(this).data('role') == 'ca:form') return true;
if (this.tagName == 'SPAN' && $(this).data('role') == 'ca:label') return true;
if (this.tagName == 'BUTTON' && $(this).data('role') == 'ca:button') return true;
}).first();
Using .first grabs the first of them.
Also, filter can be used in a million ways to get what you want and sounds like it may get you to what you need. Just set what you're filtering for in an if/for/switch statement and return true on items that match.
jsFiddle
However, if you wanted first of each you could do something like:
$('div[data-role="ca:form"]:first, span[data-role="ca:label"]:first, button[data-role="ca:button"]:first')
If variable driven in someway, just use string concatenation.
jsFiddle

Selecting a div unselects the other divs like a radio button?

I have created a list of divs using a loop from the database..
when i click select..it becomes like
the problem i am facing is that at a time i can select only one company...how could i select a nother company that will make the previous selected company unselect...
the program is like this...
{section name=i loop=$id7}
<div class="company" style="width:220px; height:220px; background-color:white;margin-left:12px;margin-bottom:22px;float:left;" >
<div id="ctable">
<table style="margin-top:20px;margin-left:18px;width:178px;height:149px;">
<tr style="text-align:center;">
<td colspan="2" align="center" valign="center" height="42px">{$id7[i].vCompanyName}</td>
</tr>
<tr>
<td colspan="2" align="center" valign="center" height="107px">
<img src="{$tconfig.tsite_images}{$id7[i].vImage}">
</td>
</tr>
</table>
</div>
<div id="selecty" class="{$id7[i].iEmployerId}" style="width:178px;height:32px; margin-left:18px;">
Select
</div>
<div id="selected_state" style="width:198px;height:32px;display:none;background-color:white;margin-left:16px;">
<img src="{$tconfig.tsite_images}tick.png" /> <font color="#cdcdcd"><b>Company selected</b></font>
</div>
</div>
{/section}
and its javascript is like this
<script>
function selecty_hide (eid,compid) {
alert(eid);
alert(compid);
document.getElementById('selecty').style.display="none";
document.getElementById('selected_state').style.display="block";
document.getElementById('eid').value=eid;
}
</script>
Say you have a class(selected_company) for selected company div.
When someone choose any other div then get previous selected div and remove this class then add this class in current selected div.
Something like this:
$(".selected_company").removeClass('selected_company');
$(this).addClass('selected_company');
Then at a time only one company will be selected.
Here is an example demo: http://jsfiddle.net/kRD4S/
Well little modification in javscript can be done as below
<script>
function selecty_hide (eid,compid,element) {
alert(eid);
alert(compid);
document.getElementById('selecty').style.display="none";
document.getElementById('ctable').style.display="none";
document.getElementById('selected_state').style.display="none";
element.style.display="block";
document.getElementById('eid').value=eid;
}
need to pass another parameter during function call(3rd param) as 'this'
onclick="selecty_hide('{$id7[i].iEmployerId}','{$smarty.section.i.index}',this)"
The script above will first display none all the div with id selecty,ctable,selected_state and this will display block the selected div.
Hope this Help you
If you can use jquery it is easy
<div class="mydiv" style="cursor: pointer;">
box 1
</div>
<div class="mydiv" style="cursor: pointer;">
box 2
</div>
<div class="mydiv" style="cursor: pointer;">
box 3
</div>
<script type="text/javascript">
$(".mydiv").click(function() {
if($(this).hasClass("selected") == false) {
$(".mydiv").removeClass("selected");
$(this).addClass("selected");
} else {
$(".mydiv").removeClass("selected");
}
});
</script>
This will remove the class "selected" from all elements with class "mydiv" and then add it to the single element you have clicked.
It also supports unselecting the current element + you can drop your buttons completely it is enough to click on the div!
You should be able to adjust my example to your code.
All you need to do now is define a custom class for the div that will display its content different like only show "company selected" when the div has the class "selected".
Have fun and good luck!
Think of it slightly different. If Company A is selected, and the user now selects Company B:
Unselect ALL elements.
Now select Company B
If you do it like this, there's no hassle in trying to figure out which company you need to unselect.
Something like this:
$(".company").click(function() {
//remember the new item
var clickedItem = $(this);
//unselect everything
$(".company").removeClass("companySelected");
//select the company that was clicked
clickedItem.addClass("companySelected");
});
Look, its simple, you can just solve your problem this way: Adding and removing CSS Classes.
I have made a full JSFiddle here to you know what i'm talking about.
Modified the HTML Company Div to be only one and not two divs:
<div id="selecty" class="selectable_state" onclick=select_unselect('{$id7[i].iEmployerId}','{$smarty.section.i.index}') >
Select
</div>
And modified the js:
function select_unselect(eid,compid){
alert(eid);
alert(compid);
if ($(this).hasClass('selectable_state'))
{
$(this).removeClass('selectable_state');
$(this).addClass('selected_state');
$(this).html('Company Selected');
$('#eid').val(eid);
}else{
$(this).removeClass('selected_state');
$(this).addClass('selectable_state');
$(this).html('Select');
$('#eid').val('');
}
}
Ps: please note that in the fiddle i removed some parameters of the function to make it work because i do not have all the data to make it work properly.

Categories