I use sockte.io to get my data from the server, and depends of the data(item.text) I have to change the images.
I tried to acces to the DOM and modify the image using a Directive but no luck.
This my code:
HTML:
<table>
<tr ng-repeat="item in items" myDirective>
<td><img ng-src="{{myImages}}" ></td> <td>{{item.text}}</td>
</tr>
</table>
JS:
App.directive('myDirective', function(){
return {
link: function($scope, elm){
console.log('eee', elm);
elm[0]['children'][0]['children'][0].attr('src',"/url/to/the/image");
}
}
});
How can I fix that, or if there is a better way to do that.
UPDATE:
At a given time the images are not the same, I want to acces to the index of each image using their index.
UPDATE:
I added this example, how can I modify for example the image that have 'text 2'
You shouldn't need a directive for this. Use ng-src instead of the normal src attribute for images.
Related
I have a code that looks something like this:
<tr ng-repeat="obj in objs">
<td onClick = "someFunction({{obj.val1}})">{{obj.val2}}</td>
<td>{{obj.val3}}</td>
</tr>
The colums properly show val2 and val3, but the onclick method I'm trying to define doesn't work as the code doesn't translate from {{obj.val1}} into the proper value, it stays as is.
How do I properly send {{obj.val1}} onto the onClick event? Can this be done?
Use ng-click instead of onClick and assign the someFunction() function to angular $scope
Yes it can be done.Using ng-click
<tr ng-repeat="obj in objs">
<td ng-click = "someFunction(obj.val1)">{{obj.val2}}</td>
<td>{{obj.val3}}</td>
</tr>
You don't need to bind the values using {{}}, you can simply put them as function parameters.
In angular they already have directive called ng-click The ngClick directive allows you to specify custom behavior when an element is clicked. which used for click event. And You don't need to bind the parameter {{}}
then your code come like
<tr ng-repeat="obj in objs">
<td ng-click = "someFunction(obj.val1)">{{obj.val2}}</td>
<td>{{obj.val3}}</td>
</tr>
Do this :
<td onClick = "someFunction(obj.val1)">{{obj.val2}}</td>
I have a table with some data:
<table id="myTable">
<thead>
<tr>
<th><h1>Name</h1></th>
<th><h1>Picture</h1></th>
<th><h1>Likes</h1></th>
<th><h1>Time</h1></th>
</tr>
</thead>
<tbody>
***loop***
<tr>
<td>{placeholder1}</td>
<td><img src="{placeholder2}" alt=""></td>
<td>{placeholder3}</td>
<td>{placeholder4}</td>
</tr>
***end loop***
</tbody>
</table>
I have a js function who gets some data from server by POST request every 10 minutes. <tr></tr> block needs to be repeated several times.
HTML code become more and more complex and I need a solution with layouts and placeholders. I need a direction to search :)
All I need is:
Store <tr></tr> pattern with placeholders to insert it into my webpage. How could I achieve it with js?
How could I mark the places where I need data to be inserted?
Okay since you are using jQuery,
This may be your HTML
<table>
<tbody id="myTableBody">
<!-- Your elements will be placed here -->
</tbody>
</table>
I will assume you are using $.ajax or $.post in either of those, add a callback function property success
$.ajax({
// ... your properties,
success: function(data) {
// basic template for of your "tr"
var trTemplate = [
'<tr>',
'<td></td>',
'<td><img src="" alt=""></td>',
'<td></td>',
'<td></td>',
'</tr>'
].join('')
// get the tbody elemen
var $myBody = $('#myTableBody')
// if you want to clean up the current content of $myBody,
// if it is not the case just remove the following line
$myBody.empty()
// assuming data is an array of elements / entities
data.forEach(function(element){
var $tr = $(trTemplate)
$tr.find('td').eq(0).text(element.placeholder1)
$tr.find('img').attr('src', element.placeholder2)
$tr.find('td').eq(2).text(element.placeholder3)
$tr.find('td').eq(3).text(element.placeholder4)
$myBody.append($tr)
})
}
})
This is example of how you could do it, there are many ways to improve this for performance and so on. Please use it only as reference
If you're using jQuery then this is pretty straightforward. You need to id your elements so that you can reference them individually. Say you start with:
<tr id="tr-0" >
content...
</tr>
and then in javascript..
var id = $('#tr-0').attr('id');
var num = parseInt(id.substring(3));
num++;
$('#tr-0').after('<tr id='+num+'>content...</tr>');
obviously you need to figure how you're getting the content for each row but hopefully you can see that it wouldn't be too hard to fill each row with custom data.
Although you can use jQuery, simpler ways exist. jQuery will require you to add additional steps that aren't really necessary. If you want to use as few Javascript packages as possible, go with jQuery.
But, I highly recommend Vue.js for Laravel projects. There are instructions from Laracasts on how to set it up. But, I have created a jsfiddle with a working set of Vue.js with the v-for directive. Checkout the JSFiddle here.
If you have questions, I'll answer as much as I can.
im very new to AngularJS and now I wrote my first directive.
The directive represents a table row and the markuplooks like the following:
<table>
<!--thead ...-->
<tbody>
<my-directive ng-repeat="(key, value) in object"></my-directive>
</tbody>
</table>
But the directive is renderd / printed out before the sorrounding table tags.
So my DOM looks like this:
<!-- multiple times -->
<my-directive></my-directive>
<table>...</table>
Heres my directive definition
return {
restrict: "E",
templateUrl: "/my-directive.html",
link: function(scope, element, attrs){
}
};
So why does this happen?
Other than tr, td, tbody, th elements never gonna work inside the table element. You should really use attribute directive so that it can support inside table to by doing restrict: "A", in directive.
<tbody my-directive ng-repeat="(key, value) in object">
</tbody>
If you want to have the other than table element to be there, then they could be placed inside th & td
Kind of going along with what Pankaj said, you can't call the directive from inside the table, its invalid HTML.
However, I can understand why you would want to use restrict: 'E'. Personally, I like using my directives as elements.
So, if you want to still use the directive as an HTML element The simplest fix to this would be to have your directive itself render the whole table. It could be a <table-for/> directive, or something like that.
This has been my workaround for this problem. Markup is markup at the end of the day, and you still have to play by the rules.
So I came to the following approach:
<tbody>
<tr my-directive ng-repeat="..."></tr>
</tbody>
And I restricted my directive to argument and it works. Thank you for your help.
So I am basically creating a table with nested ng-repeat.
<div ng-controller="PresetManageController">
<table>
<in-preset ng-repeat="preset in presetManage.presets"></in-preset>
</table>
</div>
And the template of directive in-preset is
<tr>
<td>{{preset.name}}</td>
<td>一些属性</td>
<td>
编辑
删除
</td>
</tr>
Directive declaration
module.directive('inPreset', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'scripts/directive-templates/in-preset.html'
}
});
But when I open the page, I found that all trs jumped outside of the table.
If I change table to div, then it works fine. I have checked all html tags are perfectly closed. It is damn hard to debug this issue. Any clues?
The issue is because you are using ng-repeat on a custom directive (set to replace). There are a few weird behaviors with ng-repeat and replacing directives (see related post).
Try to leave the <tr> in your html and change your directive to be on an attribute instead.
html
<table>
<tr in-preset ng-repeat="preset in presets"></tr>
</table>
js
.directive('inPreset', function() {
return {
restrict: 'A',
template: '<td>{{ preset.name }}</td>',
};
})
See the Fiddler
I've been trying to use filamentgroup's tablesaw ( https://github.com/filamentgroup/tablesaw ) in angularJS (I really love this feature filled table), but i have no idea how to start. Many articles seems to point towards using AngularJS's directives in converting existing JQuery plugins to Angular's Directives. Does that mean for every JQuery tag i'm using from Tablesaw, i have to rewrite the entire JQuery function from Tablesaw over to Angular?
Understanding that Angular wants us to avoid DOM manipulation from JQuery, and to rethink how we develop our apps. However, it doesn't make sense to forego hundreds of well done JQuery libraries available online and just waste time and effort to rewrite libraries to work in the way Angular wants.
Really appreciate anyone to kickstart me with JQuery TableSaw and Angular. Thanks in advance!
I got tablesaw to work for a table where the rows are generated by ng-repeat with the following directive:
app.directive("tableSaw", ['$timeout', function ($timeout) {
return {
restrict: 'A',
link: function($scope, element, attr) {
if($scope.$last === true) {
$timeout(function () {
$(document).trigger("enhance.tablesaw");
});
}
} // end link
};
}]);
The key being the call to tablesaw only works after the complete table has been rendered, this is why I am applying the directive row-wise, so it can initiate tablesaw only after the final row has been rendered.
Here's my table (note the table-saw directive applied alongside ngRepeat):
<div id="myContainer" ng-controller="AdminUserListCtrl as vm">
<table id="myTable"
class="tablesaw tablesaw-stack" data-tablesaw-mode="stack">
<thead class='study-list-header'>
<tr>
<th scope="col" data-tablesaw-sortable-col>
Name
</th>
<th scope="col" data-tablesaw-sortable-col>
Email
</th>
</tr>
</thead>
<tbody id="studyListData">
<tr class="study-list-row"
ng-repeat="elem in vm.usersList"
table-saw>
<td>{{elem.last_name}}, {{elem.first_name}}</td>
<td>
{{elem.email}}
</td>
</tr>
</tbody>
</table>
</div>
My includes are:
require('jquery');
require('../../node_modules/tablesaw/dist/tablesaw.css');
require('../../node_modules/tablesaw/dist/tablesaw.jquery.js');
I do not include tablesaw-init.js (it results in an error and should be absent in the case of manual initialization as specified in their docs).
A note on the call to $(document). The docs in the tablesaw git page specify that for manual initialization of tablesaw on an element we should call trigger("enhance.tablesaw") on any parent element and tablesaw will scan the tree and enable itself on all child elements that have the correct tablesaw markup. It is up to you if you want to call it on $document or perhaps on some kind of predefined parent element.