Ng-show not working as expected? Angular - javascript

As is my understanding of Angular, only one of the two following elements should be visible at a time, but for some reason, both are displaying. Is there a mistake in my code I just can't see?
Am I using ng-show incorrectly?
<div class="no_people" ng-show="!person.name">
<p>no people</p>
</div>
<div ng-repeat="person in details.people">
<div class="persons_table">
<table>
<tbody>
<tr class="top_row">
<td colspan="2">
<span class="person_name">
{{ person.name }}
</span>
<span class="person_address" >
{{ person.address }}
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>

I think this way it should work:
<div class="no_people" ng-hide="details.people.length">
<p>no people</p>
</div>
The person variable is only accessible inside the ng-repeat.
And using ng-hide instead of ng-show=! is maybe a bit more cleaner.

As I can see, you need this:
<div class="no_people" ng-hide="details.people.length > 0">
<p>no people</p>
</div>

Related

Ko Bindings after #Html.Partial do not work

I Have the following code cshtml
<div class="container-fluid" id="dvUserData">
<div class="tab-pane fade" id="documentos" role="tabpanel" aria-labelledby="documentos-tab">
#Html.Partial("Documentos")
<div class="col-md-3">
<button type="submit" class="btn btn-primary botao-vert" data-bind="click: editData">SALVAR</button>
</div>
</div>
and the following binding
ko.applyBindings(model, document.getElementById("dvUserData"));
But my data-bind="click: editData" does not work, the click is not performed. But if i put the div class="col-md-3" before the #Html.Partial("Documentos") the bindings work.
I have no idea why, I looked for posts here but could not find anything similar.
Thanks in advance for any help.
---EDITED
The Partial
<div class="row" id="dvDocument">
<form role="form">
<div class="row">
<div class="col-12">
<table class="table tabela-documentos">
<tbody data-bind="foreach: documentsReturn().documentTypes">
<tr class="bg-cinza">
<td>
<div class="aviso-sucesso" data-bind="visible : hasAllDocuments()"></div>
<div class="aviso-critica" data-bind="visible : !hasAllDocuments()"></div> <span data-bind="text: Description"></span>
</td>
<td>
<span class="d-none" data-bind="value: IdTypeDocument"></span>
<a class="btn btn-secondary" data-bind="click: function () { $parent.saveTypeDocument(IdTypeDocument); $('.alerta-form2').hide();}" data-toggle="modal" data-target="#modalDocumento">
ADICIONAR
</a>
</td>
</tr>
<!-- ko foreach: DocumentsArray() -->
<tr>
<td><i class="fa fa-file-text-o" aria-hidden="true"></i> Inclusão: <span data-bind="text: NewDate"></span></td>
<td>
<i class="fa fa-times pointer" data-toggle="modal" data-target="#modal-confirmation" aria-hidden="true" data-bind="visible : !frombase(),
, click: function(){ #*if (confirm('Deseja realmente deletar o documento?')) {*# $parent.savePath(Path); #*}*# }"></i>
</td>
</tr>
<!-- /ko-->
</tbody>
</table>
</div>
</div>
<div class="alert-button">
</div>
</form>
</div>
I forgot to mention that i have another javascript file that bindings the div document with a different model.
Press the F12 and check for any knockout js init (ko.applyBindings) error.
If there is any, fix it and try.
If no error exist, then make sure you have set a value to the model.Name() property by debugging the code.
and check your partial view and see whether you have narrow down the scope/ binding context to another complex property of you model which also has the Name property.
It would be better if you could give more info about partial view binding declaration and the how you are setting / loading the initial values to your model.
After looking for the solution and talk with some friends i found out what was the problem. I was binding the major div, that had the div id "documentos", and another information, and this was the problem.
I remove the binding of dvUserData, and put the binding in all the div that i had, including creating a new div just for the button.
This is how my div "documentos" is now.
<div class="tab-pane fade" id="documentos" role="tabpanel" aria-labelledby="documentos-tab">
#Html.Partial("Documentos")
<div class="alert-button mb-3">
<div id="dvDocumentValidate">
<button type="submit" class="btn btn-primary botao-vert" data-bind="click: editData">SALVAR</button>
</div>
</div>
</div>
And my bindings
ko.applyBindings(model, document.getElementById("dvLoading"));
ko.applyBindings(model, document.getElementById("personaldata"));
ko.applyBindings(model, document.getElementById("address"));
ko.applyBindings(model, document.getElementById("databank"));
ko.applyBindings(model, document.getElementById("dvDocumentValidate"));
ko.applyBindings(model, document.getElementById("corporatedata"));

Clickable link inside UI Sortable field

I am making a custom field for the Advanced Custom Fields plugin for wordpress.
Now I have been able to allow javascript to be used inside of the field but the field has UI-sortable active which makes my anchor tag not firering but instead clicks the sortable anchor.
Is there a way to make sure that my click event gets fired inside a sortable element?
So I created this link, to be placed inside a element :
<a id="addTable" href="#">Voeg tabel toe</a>
Which gets turned into an element like this :
<div id="normal-sortables" class="meta-box-sortables ui-sortable">
<div id="acf-group_5a93d53605864" class="postbox acf-postbox seamless">
<button type="button" class="handlediv" aria-expanded="true">
<span class="screen-reader-text">paneel Bridge verbergen</span>
<span class="toggle-indicator" aria-hidden="true"></span>
</button>
<h2 class="hndle ui-sortable-handle">
<span>Bridge</span>
<a href="{link}/wp-admin/post.php?post=12695&action=edit"
class="dashicons dashicons-admin-generic acf-hndle-cog acf-js-tooltip"
title="Bewerk groep">
</a>
</h2>
<div class="inside acf-fields -top">
<div class="acf-field acf-field-Bridge acf-field-5a93d538671c7"
data-name="bridge"
data-type="Bridge" data-key="field_5a93d538671c7">
<div class="acf-label">
<label for="acf-field_5a93d538671c7">Bridge</label>
</div>
<div class="acf-input">
<!-- Here is the anchor tag -->
<a id="addTable" href="#">Voeg tabel toe</a>
<div id="ContentWrapper">
<div id="North"></div>
<div id="East"></div>
<div id="Middle">
<table bgcolor="#c0c0c0">
<tbody>
<tr>
<td colspan="3" align="center"><strong>N</strong></td>
</tr>
<tr>
<td align="left"><strong>W</strong></td>
<td> </td>
<td align="right"><strong>O</strong></td>
</tr>
<tr>
<td colspan="3" align="center"><strong>Z</strong></td>
</tr>
</tbody>
</table>
</div>
<div id="South"></div>
<div id="West"></div>
</div>
</div>
</div>
<script type="text/javascript">
if ( typeof acf !== 'undefined' ) {
acf.postbox.render({
"id": "acf-group_5a93d53605864",
"key": "group_5a93d53605864",
"style": "seamless",
"label": "top",
"edit_url": "http:\/\/{link}\/wp-admin\/post.php?post=12695&action=edit",
"edit_title": "Bewerk groep",
"visibility": true
});
}
</script>
</div>
</div>
</div>
(function($) {
$("#addTable").click(function () {
alert( "Click" );
});
})(jQuery);

Composable Ractive js component

I'm working on a Ractive js component that represents a table. It works ok but recently I added some functionality: filters, status bar, left column checkboxes, table header. This table component is used throughout the application everywhere.
The problem is that in different places I need only some combination of these functions. In the current implementation I have a lot of ifs in the template and I want to get rid of them.
At the moment I want to use the decorator pattern but have no idea how to implement this especially with the fact that I need to mess with the core table template.
Table template:
{{#if status_bar}}
<table class="list-status">
<tbody>
<tr>
<td><input type="checkbox" checked="{{.select_all}}"></td>
<td>
{{#if has_filters}}
<span>Показать:</span>
{{#each filters:i}}
<button on-tap="#this.fire('activateFilter', event, i)" {{#if active}}class="active"{{/if}}>{{title}}</button>
{{/each}}
{{/if}}
{{#if ready}}
<span class="badge lists-badge">{{ collection.total_count }}</span>
{{#if selected.length > 0}}
<span class="badge lists-badge" style="background-color: red;">{{ selected.length }}</span>
{{/if}}
{{/if}}
</td>
</tr>
</tbody>
</table>
{{/if}}
<table class="{{class}}">
{{#if header}}
<thead>
<tr>
{{^hideSelectColumn}}
<th></th>
{{/hideSelectColumn}}
{{#each titles}}
<th class={{class}}>{{title}}</th>
{{/each}}
</tr>
</thead>
{{/if}}
<tbody>
{{#if ready}}
{{#each diff_create:i}}
<tr class="just-created">
{{^hideSelectColumn}}
<td class="{{firstColumnClass}}">
<div style="position: relative;"></div>
</td>
{{/hideSelectColumn}}
{{>pending}}
</tr>
{{/each}}
{{#if diff_create.length > 0}}
<tr>
<td colspan={{column_count}}></td>
</tr>
{{/if}}
{{#each page_models}}
<tr {{#if mfd}} class='mfd' {{/if}}>
{{^hideSelectColumn}}
<td class="{{firstColumnClass}}">
<input type="checkbox" class="list-checkbox" name='{{selected}}' value='{{#index}}'/>
<div style="position: relative;"></div>
</td>
{{/hideSelectColumn}}
{{>content}}
</tr>
{{/each}}
{{^page_models}}
<tr>
<td style='text-align:center; font-weight: bold; font-size: 15px' colspan={{column_count}}>Пусто!</td>
</tr>
{{/}}
{{/if}}
{{^ready}}
<tr>
<td style='text-align:center; font-weight: bold; font-size: 15px' colspan={{column_count}}>Загрузка...</td>
</tr>
{{/ready}}
</tbody>
</table>
<div class="pages">
{{#if pages_more_than_one}}
<ul class="pagination">
{{#if has_prev_page}}
<li class="arrow-left"><a on-tap='prevPage'><span class="icon-arrow-left4"></span></a></li>
{{/if}}
{{#each pages}}
<li class='{{#index+1==current_page ? "active": ""}}'><a on-tap='#this.fire("goToPage", #index+1)'>{{#index+1}}</a></li>
{{/each}}
{{#if has_next_page}}
<li class="arrow-right"><a on-tap='nextPage'><span class="icon-arrow-right8"></span></a></li>
{{/if}}
</ul>
{{/if}}
<div class="pages-count">
<select class="form-control" value="{{collection.perpage}}">
<option value='2'>2</option>
<option value='5'>5</option>
<option value='10'>10</option>
<option value='15'>15</option>
<option value='20'>20</option>
<option value='25'>25</option>
</select>
</div>
</div>
Thanks in advance.
Ractive has named yields where you can define placeholders in your layout and let the consuming component define what goes in there. Think of it like a layouting mechanism.
A simple example is a modal, where you have a header, body and footer which may be different for each instance. A modal component could be defined only as the layout of the modal (think empty bootstrap modal) and a bunch of yields resembling insertable positions.
const Modal = Ractive.extend({
template: `
<div class="modal">
<div class="modal__header">{{yield header }}</div>
<div class="modal__body">{{yield body }}</div>
<div class="modal__footer">{{yield footer }}</div>
</div>
`
})
On the consuming component, you use the layout component and define what goes in those positions. Note that the yield contents can be anything, even other components.
const Page = Ractive.extend({
components: { Modal },
template: `
<div class="page">
<div class="page__stuff">
...
</div>
<Modal>
{{#partial header }}
This is the header
{{/partial}}
{{#partial body }}
This is the body
{{/partial}}
{{#partial footer }}
This is the footer
{{/partial}}
</Modal>
</div>
`
});
In your case, you can break up your table into components (i.e. filters, status bar, left column checkboxes, table header) and define a layout component. Then, whenever you need it, you use the layout component, stick into it whatever you want wherever you want.
A more advanced feature is Anchors. Together with ractive.attachChild() and ractive.link(), you can attach components to anchors manually, on-the-fly. It's essentially how Ractive mounts components and binds data when it sees a component on the template. Except this time, the functionality is exposed on the API.

Bootstrap two column layout and ng-repeat (angularjs)

I'm trying to create a two col layout with ng-repeat.
<div class="row">
<div class="col-md-6" ng-repeat="item in items">
Item: {{item}}
</div>
</div>
This results in the following problem:
P.S. This problem has been answered before with native CSS cols but I want to do it with bootstrap.
P.S. The solution proposed below is not working.. anyone got any other ideas please?
You'll have to break it into two seperate columns, but it should be pretty easy after that:
<div class="row">
<div class="col-md-6" ng-repeat="item in items | limitTo: items.length /2: 0">
Item: {{item}}
</div>
<div class="col-md-6" ng-repeat="item in items | limitTo: items.length /2: items.length /2">
Item: {{item}}
</div>
</div>
for that i'm taken two tables
keep bootstrap styles
<table> <tr ng-repeat="cl in codelist" ng-if="$index<codelist.length/2">
<td>{{$index}}</td>
</tr></table>
<table> <tr ng-repeat="cl in codelist" ng-if="$index>=codelist.length/2">
<td>{{$index}}</td>
</tr></table>
that it show order by ordey
1 3
2 4
5 6
like this

Trouble with ng-repeat angular js

I have an angular ng-repeat like bellow,
<div class="row" >
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
</div>
This will create output like below,
<div class="row" >
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
-----------------------
----------------- Etc.
</div>
But i need to repeat <div class="row" > also which contain two <div class="col-md-6" in each row.
This output needs like
<div class="row" >
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
</div>
<div class="row" >
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
</div>
<div class="row" >
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
<div class="col-md-6" ng-repeat="(index,data) in mydata">
<-- my content -->
</div>
</div>
------- Etc
Is it possible to do with this usingng-repeat?
As mentioned in comment, if you want your row to repeat with each element in mydata, you would need to put ng-repeat on the <div> that contains row.
Its upto you to decide if you want to hardcode the inner <div> like this:
<div class="row" ng-repeat="data in mydata">
<div class="col-xs-6"> {{data.index}} </div>
<div class="col-xs-6"> {{data.value}} </div>
</div>
or use another ng-repeat on it.
<div class="row" ng-repeat="(index,data) in mydata">
<div class="col-xs-6" ng-repeat="i in data"> {{i}} </div>
</div>
Where mydata is an array of json with following structure:
$scope.mydata = [{index:0,value:'hello'},
{index:1,value:'hello1'},
{index:2,value:'hello2'}
]
here's the plunkr
UPDATE:
If you have data like following,
$scope.mydata = [{value:'hello0'},
{value:'hello1'},
{value:'hello2'},
{value:'hello3'}];
and you want to display it like
hello0 hello1
hello2 hello3
in the view, then you would need to make a check for elements occurring at even iterations and print elements at $index and $index+1. I used $even for the same. but you can also create a custom filter.
<div class="row" ng-repeat="data in mydata">
<div ng-if="$even">
<div class="col-xs-6" > {{mydata[$index].value}} </div>
<div class="col-xs-6" > {{mydata[$index + 1].value}} </div>
</div>
</div>
Heres the updated plunker
Create a directive:
angular.module(....)
.directive('myRows',function(){
return {
restrict : 'A',
template : '<div class="row"><div class="col-md-6" ng-repeat="(index,data) in mydata"><-- my content --></div></div>'
};
});
assumption here is that mydata is defined on the scope of the surrounding controller.
Use it in your html:
<div data-my-rows><div>
Yes ng-repeat is possible to do that.
Here is example code from my project
<tbody>
<tr ng-repeat="proj in projects>
<td>
{{proj.projectID}}
</td>
<td>
{{proj.projectName}}
</td>
<td>
{{proj.project.start date | date:'mediumDate'}}
</td>
<td>
{{proj.projectStatus}}
</td>
</tr>
</tbody>
I hope this would help
So, you now have two answers that correctly address your question and will produce the results you requested, but I wanted to give you some advice (albeit unsolicited) about your Bootstrap structure.
In Bootstrap, it is perfectly acceptable to not repeat your rows for every 12 grid units. In fact, if you want to use multiple responsive column classes together, such as using col-lg-4 and col-md-6 to produce 3 columns on large viewports and 2 on medium viewports, you cannot insert rows between your repeated content.
Since col classes use float and percentages, you don't have to worry about "terminating" the row. Elements will simply float next to one another up to 12 grid units and then start a new natural horizontal "row." That is how Bootstrap's responsive grid works.
You should use rows for two purposes:
To nest columns inside of columns. See my answer here for a
visual explanation of this topic. or
To create horizontal groups of columns. This has the purpose of grouping elements together and clearing column floats for subsequent columns.
What I'm saying is that your initial ng-repeat structure was better and will provide you with a more flexible outcome.

Categories

Resources