\n breaking PHP code within Javascript - javascript

When I run this code on my PHP website, it works but when adding a \n after 'text:' as php to make a new line, the entries in the table below the blue title at the top stop showing. Below is a snippet of what the code is but it does not run php so it doesn't show the error.
function MyCtrl($scope) {
$scope.environment_service_packages =
[
{name: 'obj1', info: {text: '<?php echo "This: \n breaks the code"; ?>', show: true}},
{name: 'obj2', info: {text: 'some extra info for obj2', show: false}},
];
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app>
<table ng-controller="MyCtrl" class="table table-hover table-striped">
<tr class="info">
<td>...</td>
</tr>
<tbody ng-repeat="x in environment_service_packages">
<tr ng-click="x.info.show = !x.info.show">
<td> {{ x.name }}
</tr>
<tr ng-show="x.info.show">
<td>
{{ x.info.text }}
</td>
</tr>
</tbody>
</table>
</body>

You actually need to escape the line-break twice.
One escape for JavaScript and one for php
Your current string generates this php:
<?php echo "This:
breaks the code"; ?>
because the \n is evaluated by javascript into a linefeed character and this makes the php invalid.
You should use this string instead:
'<?php echo "This: \\n does not break the code"; ?>'

\n will not show in HTML. You have to coding like this.
function MyCtrl($scope) {
$scope.environment_service_packages =
[
// <br> will be convert to <br>
{name: 'obj1', info: {text: '<?php echo "This: <br> breaks the code"; ?>', show: true}},
{name: 'obj2', info: {text: 'some extra info for obj2', show: false}},
];
}

Related

How to properly sort a normal US date using the JS Data Tables plugin

I have a batch of dates in the format mm/dd/yyyy and associated names that need to be sorted with data tables. These dates are echod in a loop using PHP. My code (index.php) looks like this:
<!--
Assume datatables plugin is loaded, and
a PHP var named $arr is loaded and has the
structure:
$arr['mm/dd/yyyy'] => 'name'
-->
<table class="table cdates">
<thead>
<tr>
<th>Date</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<?php
foreach($arr as $date => $name){
?>
<tr class="crow">
<td><?php echo $date; ?></td>
<td><?php echo $name; ?></td>
</tr>
<?php
}
?>
<tbody>
</table>
Inside of a javascript file, named cdatatable.js that has already been loaded, I have the following code:
$(document).ready(function(){
$('.cdates').DataTable({
pageLength:25,
responsive:true,
dom: '<"html5buttons"B>lTfgitp',
buttons: [
{extend: 'copy'},
{extend: 'csv'},
{extend: 'excel', title: 'name'},
{extend: 'pdf', title: 'name'},
{extend: 'print',
customize: function (win){
$(win.document.body).css('font-size', '10px');
$(win.document.body).find('table')
.addClass('compact')
.css('font-size', 'inherit');
}
}
]
});
});
The datatables will properly sort the name, but unfortunately, it treats the date as a string and therefore sorts it by digit. For example if I have the following table:
Date Name
--------- | -------
01/02/2003 My Name
12/01/2012 Hello world
06/20/2002 Name 2
And I sort it by Date, it currently returns:
Date Name
--------- | -------
01/02/2003 My Name
06/20/2002 Name 2
12/01/2012 Hello world
It should be returning:
Date Name
--------- | -------
06/20/2002 Name 2
01/02/2003 My Name
12/01/2012 Hello world
I've seen tons of other questions about sorting different countries dates, however none seemed to really apply to me. I've also tried converting the string to a date in JS and then applying that value to the row. It doesn't seem to work though and the same issue happens.
Is there a way in PHP that I could convert my date to one that can be recognized in JavaScript maybe? Or if that isn't possible, is there something I can add to dataTables to recognize my column as a "date" column?
The easiest solution would be to replace this line:
<td><?php echo $date; ?></td>
with the line below:
<td data-order="<?php echo strtotime($date); ?>"><?php echo $date; ?></td>
Another solution would be to modify date-uk plug-in to accept date in mm/dd/YYYY format but solution shown above would be easier and possibly faster.
<table class="table cdates">
<thead>
<tr>Date</tr>
<tr>Name</tr>
</thead>
should be
<table class="table cdates">
<thead>
<tr>
<th>Date</th>
<th>Name</th>
</tr>
</thead>

Show /hide warning messag based on filtered outputs ng-repeat

Please find the attached fiddle where I want to post a warning mesaage "No data to display" if the filter fais to match any results in the button clicks.
Fiddle ng-repeat filter
I have given condition for both table and message so that they should be displayed as and when the clicks happen.
<div ng-show="name===null">No results</div>
The above message should be displayed if there are no satisfying data in the table based on link clicks,together the table should be hidden.
I tried to give conditions based on property name but its not working.
Check your fiddle http://jsfiddle.net/w0L4o8jm/6/
By default I am making filter with Fruit. You can change it in the controller.
Coming to the answer, Calculate the filtered items length according to the filter. If length 0 or name '', then show no results. Otherwise show results in the table. Just copy paste the below code in your fiddle and check it out.
<html ng-app="app">
<a ng-click="name = 'Fruit'">Fruit</a>
<a ng-click="name = 'Nut'">Nut</a>
<a ng-click="name = 'Seed'">Seed</a>
<body ng-controller="main">
<a ng-click="name = ''">clear filter</a>
<br> <br> <br>
<div ng-show="(name=='' || !filtered.length)">No results</div>
<div ng-repeat="link in filtered = (links|filter:name)"></div>
<table class="table" ng-show="(filtered.length != 0 && name!='')">
<thead>
<tr>
<th>Target</th>
<th>Level</th>
<tr>
<tbody>
<tr ng-repeat="link in links|filter:name">
<td>
{{link.name}}
</td>
<td>
{{link.category}}
</td>
</tr>
</tbody>
</table>
</body>
Controller code
var app = angular.module('app', []);
app.controller('main', function($scope) {
$scope.filters = { };
$scope.name='Fruit';
$scope.links = [
{name: 'Apple', category: 'Fruit'},
{name: 'Pear', category: 'Fruit'},
{name: 'Almond', category: 'Nut'},
{name: 'Mango', category: 'Fruit'},
{name: 'Cashew', category: 'Nut'}
];
});
For Angular prior to 1.3
Assign the results to a new variable (e.g. filtered) and access it:
<div ng-repeat="link in filtered = (links|filter:name)"></div>
For Angular 1.3+
Use an alias expression (Docs: Angular 1.3.0: ngRepeat, scroll down to the Arguments section):
<div ng-repeat="link in links|filter:name as filtered"></div>
Try to use this code
Demo
<body ng-app="app" ng-controller="main">
<a ng-click="name = 'Fruit'">Fruit</a>
<a ng-click="name = 'Nut'">Nut</a>
<a ng-click="name = 'Seed'">Seed</a>
<a ng-click="name = ''">clear filter</a>
<br> <br> <br>
<div ng-show="name ==''">No results</div>
<table class="table" ng-show="name!=''">
<thead>
<tr>
<th>Target</th>
<th>Level</th>
<tr>
<tbody>
<tr ng-repeat="link in links | filter:name">
<td>
{{link.name}}
</td>
<td>
{{link.category}}
</td>
</tr>
</tbody>
</table>
var app = angular.module('app', []);
app.controller('main', function($scope) {
$scope.filters = { };
$scope.name = '';
$scope.links = [
{name: 'Apple', category: 'Fruit'},
{name: 'Pear', category: 'Fruit'},
{name: 'Almond', category: 'Nut'},
{name: 'Mango', category: 'Fruit'},
{name: 'Cashew', category: 'Nut'}
];
});
Here you go! Updated fiddle
You had a few issues in there:
your ng-controller was on a div but you were setting name outside controller
<div ng-show="name===null">No results</div> Here you were comparing name with null but you were setting it to empty string in clear filter
Hope it helps!
Edit: On clear filter it was not showing all the items. Fixed and updated fiddle

Href not working within Javascript function

I have got this code below and I want to know how I can add a clickable link to the boxes under each title.
I want this Call on Skype to appear in the first box. But I cannot get it to work as the whole function just stops working when I add it.
function MyCtrl($scope) {
$scope.environment_service_packages =
[
{name: 'obj1', info: {text: '<?php echo "A html link below \\n\\n Call on Skype"; ?>', show: true}},
{name: 'obj2', info: {text: 'some extra info for obj2', show: true}},
{name: 'obj3', info: {text: 'some extra info for obj3', show: true}},
{name: 'obj4', info: {text: 'some extra info for obj4', show: false}},
];
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app>
<table ng-controller="MyCtrl" class="table table-hover table-striped">
<tr class="info">
<td>...</td>
</tr>
<tbody ng-repeat="x in environment_service_packages">
<tr ng-click="x.info.show = !x.info.show">
<td> {{ x.name }}
</tr>
<tr ng-show="x.info.show">
<td>
<pre>{{ x.info.text }}</pre>
</td>
</tr>
</tbody>
</table>
</body>
Putting ng-repeat on the tbody will create a body for every member in the array.
Try putting ng-repeat-start on the first row and ng-repeat-end on the second row.
You can't run PHP code in client side...
you need to change HTML to something like:
Call on Skype

Iterating over arraylist of arraylist using ng-repeat in angularjs

I am having a Json arraylist which contains another arraylist. I need to iterate over both these arraylists and display records in table.
This is what i have tried so far.
I tried using two ng-repeats in same tr.But it didnt work
<tr class="ng-scope"
ng-repeat="msgcounts in pastdata" ng-repeat="past in msgcounts.arrayList_Jsons" >
<td class="numeric">{{ 1}}</td>
<td class="numeric">{{ past.aggregator}}</td>
<td class="numeric">{{past.loadedCount}}</td>
<td class="numeric">{{past.sentCount}}</td>
<td>{{past.sentCount}}</td>
<td >{{past.failedCount}}</td>
<td class="numeric">{{past.replyCount}}</td> <td class="numeric">{{msgcounts.date}}</td>
</tr>
I tried creating a div in tr tag
<tr class="ng-scope"
ng-repeat="msgcounts in pastdata">
<div ng-repeat="past in msgcounts.arrayList_Jsons" >
<td class="numeric">{{ 1}}</td>
<td class="numeric">{{ past.aggregator}}</td>
<td class="numeric">{{past.loadedCount}}</td>
<td class="numeric">{{past.sentCount}}</td>
<td>{{past.sentCount}}</td>
<td >{{past.failedCount}}</td>
<td class="numeric">{{past.replyCount}}</td>
</div>
<td class="numeric">{{msgcounts.date}}</td>
<tr>
Here is the sample data:
{
[
{date1,[{1,1,1,1},{2,2,2,2}]},
{date2,[{1,1,1,1},{2,2,2,2}]},
{date3,[{1,1,1,1},{2,2,2,2}]},
]
}
Please suggest me what can be done in this case.
Html should look like this
you can't set two ng-repeats on one element,
and a div cannot be a direct child of a tr.
you could maybe use another tbody tag to solve this:
<tbody ng-repeat="msgcounts in pastdata">
<tr ng-repeat="past in msgcounts.arrayList_Jsons">
<td class="numeric">{{1}}</td>
<td class="numeric">{{ past.aggregator}}</td>
<td class="numeric">{{past.loadedCount}}</td>
<td class="numeric">{{past.sentCount}}</td>
<td>{{past.sentCount}}</td>
<td>{{past.failedCount}}</td>
<td class="numeric">{{past.replyCount}}</td>
<td class="numeric">{{msgcounts.date}}</td>
</tr>
</tbody>
If your data looks like the following :
$scope.groupDetails = [{
groupingNumber: '1',
groupDetails: [{
sequence: '1',
text: 'test 1',
}]
},
{
groupingNumber: '2',
groupDetails: [{
sequence: '1',
text: 'test 2',
}, {sequence: '2',
text: 'test 3', }]
},
{
groupingNumber: '3',
groupDetails: [{
sequence: '3',
text: 'test 4',
}]
}
];
In the front end you can write something like this :
<div ng-repeat="grouping in groupDetails">
<div ng-repeat = "groupSequence in grouping.groupDetails">
<div>{{groupSequence.text}}</div>
</div>
</div>

Angular newbie: non-trivial form validation?

I am new to Angular, and I would like to do some non-trivial input validation.
Basically I have a table. Each row contains three text inputs. When the user types into any text inputs, I would like to check whether the table contains at least one row with three non-blank input fields. If it does, I want to show a message.
I have no idea how to do this cleanly in Angular, any help would be much appreciated.
This is my HTML:
<tr data-ng-repeat="i in [1,2,3,4,5]">
<td data-ng-repeat="i in [1,2,3]">
<input ng-model="choice.selected" ng-change='checkAnswer(choice)' type="text" />
</td>
</tr>
...
<div ng-show="haveCompleteRow">we have a complete row!</div>
And controller:
$scope.haveCompleteRow = false;
$scope.checkAnswer=function(choice){
$scope.haveCompleteRow = true; // what to do here?
}
Here is a plunker demonstrating the issue: http://plnkr.co/edit/Ws3DxRPFuuJskt8EUqBB
To be honest, I wouldn't call this form validation. But for starters, it would be a lot simpler if you had a real model to observer, instead of an array in the template. The way you started will, or at least could, lead you to dom-manipulation inside the controller, which is a no-go for angular.
A simple first sketch with a model could be:
app.controller('TestCtrl', ['$scope', function ($scope) {
$scope.rows = [
[{text: ''}, {text: ''}, {text: ''}],
[{text: ''}, {text: ''}, {text: ''}],
[{text: ''}, {text: ''}, {text: ''}]
];
$scope.haveCompleteRow = false;
// watch for changes in `rows` (deep, see last parameter `true`).
$scope.$watch('rows', function (rows) {
// and update `haveCompleteRow` accordingly
$scope.haveCompleteRow = rows.some(function (col) {
return col.every(function (cell) {
return cell.text.length > 0;
});
});
}, true);
}]);
with:
<body ng-controller="TestCtrl">
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
<th>Col3</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="row in rows">
<td data-ng-repeat="cell in row">
<input ng-model="cell.text" type="text" />
</td>
</tr>
</tbody>
</table>
<div ng-show="haveCompleteRow">we have a complete row!</div>
</body>
as the template.
Demo: http://jsbin.com/URaconiX/2/

Categories

Resources