duplicate check for rows in smart-table - javascript

I have a duplicatecheck function which basically compares the current edited row(newRule) with the other rows in the list(ruleList). It works fine because it displays an error when duplicate coloumns are detected, but it resets if ANYOTHER row has duplicates ( my app allows user to edit the rows). I want to the error to stay and not reset, which is inside the else statement ( duplicate.error=false). In my if and else, how do I make it so that the error=true only for that specific row/index. I defined index as a paramter, so that's basically that specific row.
$scope.duplicateCheck = function (newRule, ruleList, duplicate, index) {
var error = false;
//the logic goes here, blah blah blah if duplicates detected in all the columns, error is set to true
if (error) {
duplicate.error = true;
} else {
duplicate.error = false;
duplicate.item = '';
duplicate.index = -1;
}
};
$scope.duplicateAppType = {
error: void(0),
item: '',
index: -1
};
Html (rule= row that is currently being edited also defined in my ng-model, theList=all the rows in the st-table)
<td class='errorClass'
<p ng-show="duplicateAppType.error"{{Duplicate here}}<p>
</td>
<select>
ng-model=rule.names
ng-change=duplicateCheck(rule, theList, duplicateAppType, $index)
</select>
<br>

Related

Why does this jQuery not work in one place?

I have abstracted some jQuery code to handle filtering of tables in my application. In general, the user clicks a link and certain table rows are shown or hidden. The code is below:
var filters = $('ul.filters');
var filtersCount = filters.children().length;
if (filtersCount > 2) {
filters.children(':last-child').css({
'right':'1px'
})
}
var target = filters.data('target');
$('a.filter').on('click', function() {
filters.children().removeClass('active');
$('.filterable').hide();
var $this = $(this);
$this.parents('li').addClass('active');
var visibleStates = $this.data('include-filter').split(" ");
$(visibleStates).each(function(index,state) {
if (state == "all") {
$('.filterable').show();
} else {
$('.filterable' + '.' + state).show();
}
})
if ($this.data('exclude-filter') !== undefined) {
var hiddenStates = $this.data('exclude-filter').split(" ");
$(hiddenStates).each(function(index,state) {
$('.filterable' + '.' + state).hide();
})
}
})
This code is used in five places in my application and works in four of them. By stepping through execution, I know the code does work because it filters the elements but eventually all ".filterable" elements on the page are hidden. I have followed the execution of the code which goes into this part of jQuery:
if ( ret !== undefined ) {
if ( (event.result = ret) === false ) {
event.preventDefault();
event.stopPropagation();
}
}
The line which causes the ".filterable" rows to be hidden is this:
ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ).apply( matched.elem, args );
Eventually, execution stops on this line:
return event.result;
event.result is undefined if I look at it in the console. Javascript is not really my area of expertise so if anyone can give me a point in the right direction, I would be grateful.
EDIT
I have added the simplest code possible into my table as follows with the same result. Both rows are hidden and don't reappear irrespective of which filter link I click.
<tbody>
<tr class="filterable paid-sick-leave">
<td>From</td>
<td>To</td>
</tr>
<tr class="filterable paid-annual-leave">
<td>From</td>
<td>To</td>
</tr>
</tbody>
The filters look like this. The Ruby code prints out the description of the absence category, downcasing it and replacing spaces with hyphens.
<ul class="filters">
<li class="active">
All Absences
</li>
<% #absence_categories.each do |ac| %>
<li>
<%= ac.description %>
</li>
<% end %>
</ul>
change this click event like below:
$(document).on('click','a.filter', function() {
filters.children().removeClass('active');
$('.filterable').hide();
var $this = $(this);
$this.parents('li').addClass('active');
var visibleStates = $this.data('include-filter').split(" ");
$(visibleStates).each(function(index,state) {
if (state == "all") {
$('.filterable').show();
} else {
$('.filterable' + '.' + state).show();
}
})
if ($this.data('exclude-filter') !== undefined) {
var hiddenStates = $this.data('exclude-filter').split(" ");
$(hiddenStates).each(function(index,state) {
$('.filterable' + '.' + state).hide();
})
}
})
It mean "event.result" is Null you need to test if your event click still exist after you need to debug in the console script as application step by step may be this error caused by no reference class or html.

AngularJS - A function to return value, if there is no value, return nothing within the cell

I am exporting table data as a pdf using pdfmake.
Depending if there a value set within the table, based on what is filtered within the Search dropdowns, I want to return that value. Otherwise I want to return ''.
As of now if nothing is set within the cell it will return as 'null' I want to return '' instead of null.
Here is the expression I am using from the html
<td style="background-color: #bfdfff; word-wrap: break-word;" class="routeCheckInGrid">
<span id="ContentPlaceHolder1_RouteCheckIn_Editable1_lblAccidentMcGoal">{{monday.accidentFreeDayMCG}} /day</span>
</td>
Tried creating a function that gives me the value or returns ' '.
scope.drivers is where all the data is set.
$scope.accidentFreeMC = function(monday) {
if ($scope.drivers) {
if ($scope.resultsRolledUp) {
return monday.accidentFreeDayMCG;
} else {
return '';
}
}
}
using it in the table
table: {
body: [
[
$scope.accidentFreeMC + ' /day',
],
]
}
What am i missing? Any help is much appreciated.
UPDATE**
Here is a working example of something similar that I would like to achieve.
Here is a row where depending on what Route is filtered in the search, will show data in the total column. If a specific Route is selected then nothing is shown in the cell.
$scope.wasTheLCPAuditCompleted = function(day) {
if ($scope.drivers) {
if ($scope.resultsRolledUp) {
return day.lcpAuditCompletedCount + '/' + day.dayRouteCount
}
if (!$scope.resultsRolledUp && (!$scope.dataEntryView || $scope.isRollup)) {
return day.lcpAuditCompleted == 'Y' ? 'Yes' : 'No';
} else {
return '';
}
}
}

How to have data update without page reload from firebase

I am trying to implement a simple favorites system. On the page load posts are listed on the home page and any previously favorited posts called nubs will show up with the FAVED tag underneath them.
<div class="list-group" ng-repeat="nub in nubs">
<a href="#" class="list-group-item active">
<h4 class="list-group-item-heading">{{nub.title}}</h4>
<p class="list-group-item-text">{{nub.description}}</p>
<p class="list-group-item-text">{{nub.synopsis}}</p>
<li ng-repeat="url in nub.attachmentsUrls">
<p class="list-group-item-image">
<img ng-src={{url}} />
</p>
</li>
</a>
<button ng-click="toggleFav(nub)">favorite</button>
<p ng-show="getFaved(nub.$id)">FAVED</p>
</div>
This is working but when I add something to my favorites the page doesn't update to reflect the newly favorited post. I would like to make my page respond actively to the toggleFav function.
Here is my controller
var ref = new Firebase("https://xxxxx.firebaseio.com");
var auth = ref.getAuth();
var nubRef = new Firebase("https://xxxxx.firebaseio.com/Nubs");
var nubs = $firebaseArray(nubRef);
$scope.nubs = nubs;
var userRef = new Firebase("https://xxxxx.firebaseio.com/users");
var users = $firebaseArray(userRef);
$scope.users = users;
// Array of booleans for favorites
$scope.favedArray = [];
// Array of user ids for
$scope.userIdArray = [];
var userFavs = $firebaseArray(userRef.child(auth.uid).child("favorites"));
$scope.userFavs = userFavs;
userFavs.$loaded()
.then
(
function()
{
nubs.$loaded()
.then
(
function()
{
$scope.tempFaved = [];
$scope.tempId = [];
console.log(userFavs);
angular.forEach
(
nubs,
function(nub)
{
$scope.tempFaved.push(false);
$scope.tempId.push(nub.$id);
console.log($scope.tempId);
angular.forEach
(
userFavs,
function(favs)
{
console.log($scope.tempFaved);
if(favs.nub == nub.$id)
{
$scope.tempFaved.pop();
$scope.tempFaved.push(true);
console.log($scope.tempFaved);
}
}
);
}
);
while($scope.tempFaved.length > 0)
{
$scope.favedArray.push($scope.tempFaved.pop());
$scope.userIdArray.push($scope.tempId.pop());
}
$scope.getFaved = function(nubId)
{
console.log($scope.favedArray[$scope.userIdArray.indexOf(nubId)]);
$scope.faved = $scope.favedArray[$scope.userIdArray.indexOf(nubId)];
return $scope.faved;
}
$scope.toggleFav = function(nub)
{
var nubFavRef = nubRef.child(nub.$id).child("favorites");
var nubFavs = $firebaseArray(nubFavRef);
var faved = $scope.getFaved(nub.$id)
console.log(faved);
if (faved == false)
{
nubFavs.$add
(
{
user: auth.uid
}
);
userFavs.$add
(
{
nub: nub.$id
}
)
console.log("favorited");
}
else
{
nubFavs.$remove(auth.uid);
userFavs.$remove(nub.$id);
console.log("unfavorited");
}
};
}
)
}
);
Essentially it is looping through the nubs or posts displayed on the page and checking them against the nubs the user has favorited to display the FAVED tag and toggle the functionality of the favorite button. If the user doesn't have the nub favorited the button will add the nub to their list of favorites as well as adding them to the list of users that have the nub favorited and if the user does have the post favorited it will remove them.
The unfavorite functionality of the toggleFav doesn't work either so help with that would also be appreciated, but that's a matter of being able to access the right child of the faved arrays which I'm not sure how to do.
What I think needs to happen for the page to update with the right information when something is favorited is some kind of $on listener, but I'm not sure how to implement it.
/* How store data in fire base:
{
"home" : {
"room1" : {
"status" : "true",
"switch_name" : "light 2",
"user_id" : "-Kvbk-XHqluR-hB8l2Hh"
}
}
}
*/
//select element in which you want real time data.
const preObject = document.getElementById('tbl_switch_list');
//select your root table name
const dbRefObject = firebase.database().ref().child('home');
//Change Value in Firebase and view in your console.
dbRefObject.on('value',snap => console.log('Response : ',snap.val());
<h3>Switch List</h3>
<table id="tbl_switch_list" border="1">
<thead>
<tr>
<td>#ID</td>
<td>#switchName</td>
<td>#status</td>
</tr>
<thead>
<tbody id="list"></tbody>
</table>

CasperJS querySelectorAll + map.call

html file
<table id="tbl_proxy_list">
...........
<tr>
......
<td align="left">
<time class="icon icon-check">1 min</time>
</td>
<td align="left">
<div class="progress-bar" data-value="75" title="4625"></div>
</td>
</tr>
</table>
ip.js file
casper.start('http://www.proxynova.com/proxy-server-list/', function() {
var info_text = this.evaluate(function() {
var nodes = document.querySelectorAll('table[id="tbl_proxy_list"] tr');
return [].map.call(nodes, function(node) {
//return node.innerText;
return node;
});
});
var tr_data = info_text.map(function(str) {
var elements = str;
var data = {
ip : elements,
port : elements[1],
lastcheck : elements[2],
speed : elements[3], // <== value is 75..
};
return data;
});
utils.dump(tr_data);
});
casper.run();
return node.innerText is only text.
ip is a text value
port is a text value
lastcheck is a text value
speed is not a text value (data-value="75")
I want to import data-value="75" (speed value is 75).
I do not know what to do.
========================================
It's work.. good. thank you Artjom.
but tr_data echo error.
first, you code modify..
return {
"ip": tr.children[0].innerText.trim(),
"port": tr.children[1].innerText.trim(),
"lastcheck": tr.children[2].innerText.trim(),
"speed": tr.children[3].children[0].getAttribute("data-value")
};
and echo..
//this.echo(tr_data.length);
for(var ii=0; ii<tr_data.length; ii++)
{
this.echo(tr_data[ii]['ip']);
}
at run, blow error..
TypeError: 'null' is not an object (evaluating 'tr_data.length'); what is problem?
I need your help.. thanks.
You cannot pass DOM elements from the page context (inside evaluate callback).
From the docs:
Note: The arguments and the return value to the evaluate function must be a simple primitive object. The rule of thumb: if it can be serialized via JSON, then it is fine.
Returning an array of DOM elements will result in an array of as many undefined values. That means you need to map everything inside the page context and then return the resulting array. You also need only one map.
var tr_data = this.evaluate(function() {
var nodes = document.querySelectorAll('table[id="tbl_proxy_list"] tbody tr');
return Array.prototype.map.call(nodes, function(tr, i) {
if (tr.children.length != 6) {
return null; // skip ads
}
return {
ip: tr.children[0].innerText.trim(),
port: tr.children[1].innerText.trim(),
lastcheck: tr.children[2].innerText.trim(),
speed: tr.children[3].children[0].getAttribute("data-value")
};
}).filter(function(data){
return data !== null; // filter the null out
});;
});
You also might want to trim the excess white space.

HTML.Action Loop results in wrong model on page (variable scope pollution?)

I have a view (cshtml) that has a tab strip on it. The contents of each tab is of course different. The individual tabs have the correct data/information on them. There is some javascript that is intended to fire when a selection is made from the control on the individual tab. As it stands right now the first tab rendered the javascript fires. All other tabs do not fire. Further on the tab that does fire (first one) it obtains the correct value but then when trying to find the matching item in the model it doesn't find a match. Debugging shows that only the data for the last tab is available in the model. Well that explains why no match but begs the question of where did the data the first page was populated with go?
I have snipped the code for brevity. If, in my ignorance I left something out just say so and I'll post whatever is needed.
So to start here is the parent cshtml:
foreach (var extbrd in Model.ExternalBoards)
{
tabstrip.Add()
.Text(extbrd.ExtForumName)
.ImageUrl("~/.../ForumTabIcon.png")
.Content(#<text>
<div>
#Html.Action("ActionName", "Controller", new { id = extbrd.BoardId });
</div>
</text>);
}
Well as you can see above as we loop we call an action in the controller for each tab. Here is that action:
public ActionResult ActionName(int extforumid)
{
//get url for selected forum (tab) and pull feed
ExternalForums ExtFrm = _forumService.GetExternalForumById(extforumid);
reader.Url = ExtFrm.ForumUrl;
return View(reader.GetFeed());
}
That's actually it. As above I can post the reader code but I don't think it is the source of the trouble.
Well this action of course has a view and this is where I think things get wacky:
#model ExternalThreadsModel
<script type="text/javascript">
var model = #Html.Raw(Json.Encode(Model.RssThreads))
</script>
<script type="text/javascript">
$(function() {
$("##Html.FieldIdFor(model => model.ExtForumIds)").click(function () {
var selectedItem = $(this).val();
var matchingObj = getObjects(model, 'ThreadValue', selectedItem);
if(matchingObj > 0)
{
var $iframe = $('#ForumFrame');
if ( $iframe.length ) {
$iframe.attr('src', matchingObj[0].Link);
}
var $prevfram = $('#ForumPreview');
if ( $prevfram.length ) {
$prevfram.val(matchingObj[0].Description);
}
}
});
});
function getObjects(obj, key, val) {
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(getObjects(obj[i], key, val));
} else if (i == key && obj[key] == val) {
objects.push(obj);
}
}
return objects;
}
</script>
<div>
<table>
<tr>
<td>
#Html.DropDownListFor(model => model.ExtForumIds, Model.SelectThreads, new {style = "...", #size = 30})
</td>
<td style="width:25px;"> </td>
<td>
#{ Html.Telerik().TabStrip()
.Name("ForumView")
.Items(tabstrip =>
{
tabstrip.Add()
.Text("Preview")
.Content(#<text>
<div>
<textarea style="background-color:#979797; text-decoration: none;" id="ForumPreview" name="ForumPreview" rows="26" cols="200" readonly></textarea>
</div>
</text>);
tabstrip.Add()
.Text("Interactive")
.Content(#<text>
<div>
<iframe id="ForumFrame" name="ForumFrame" src="" style="width:800px;height:350px;"></iframe>
</div>
</text>);
})
.SelectedIndex(0)
.Render();
}
</td>
</tr>
</table>
</div>
So as I mentioned each tab does have the correct data / information on it. The problem comes when a user selects an item from the drop down list.
The click handler only fires on the first tab. It doesn't fire for any other tabs???
Further on the first tab the click handler does fire and it pulls the correct selectedItem but when it runs through the helper function getobjects it doesn't find a match.
When I break and examine "model" as it is being passed into getObjects it only contains data for the last tab...so yeah nothing is going to be matched.
What is even stranger for me to understand is the line:
<script type="text/javascript">
var model = #Html.Raw(Json.Encode(Model.RssThreads))
</script>
In HTML it does render a json object with ALL the data from ALL the tabs...so...somewhere I must be running into variable scope pollution????
Your support and assistance is..as always..greatly appreciated.

Categories