I have a filter class that filters products residing inside the page.There is a function that works if someone checks the filters.
Filters are check-boxes where every check box contains different value.
What my filter function do is that it checks all the checked checkboxes from the page and then uses the data-* global variable present on the list tages to decide what element to show.
DOM structure of the items will be:
<body>
<ul class="products">
<li class="product" data-company="something" data-flavour="something"></li>
<li class="product" data-company="something" data-flavour="something"></li>
.
.
.
.
<li class="product" data-company="something" data-flavour="something"></li>
</ul>
</body>
Below one shows the the function that does the job.
this.filterGridProducts = function() {
$.ajax({
type: 'POST',
url: 'test12.php',
data: category,
success: function(data) {
$('#limitpage').html(data);
// $('.product').hide();
var filteredProducts =$('.product');
//filter by colour, size, shape etc
var filterAttributes = $('input[type="checkbox"]');
var selectedFiltersValues = [];
// for each attribute check the corresponding attribute filters selected
filterAttributes.each(function() {
if (this.checked) {
var currentFilter = $(this);
selectedFiltersValues.push("[data-" + currentFilter.attr('name') + "='" + currentFilter.val() + "']");
filteredProducts = filteredProducts.filter(selectedFiltersValues.join(','));
}
});
filteredProducts = filteredProducts.filter(function() {
return ($(this).attr('data-price') > first && $(this).attr('data-price') <= second);
});
//console.log($('.product').show());
filteredProducts.each(function(e) {
console.log($(this).html().show()); // not working
$(this).show(); // not working
})
filteredProducts.show(); // this one is not working as well.
}
});
};
filteredProducts does contain the elements that need to be filtered but I can't seem to show it.
Ajax call in the above functions loads all the elements present inside the db, The products that come from it are all hidden.
What could be the possible reason for the .show() to not work?
Update:
Related
I explain myself: I have a Sharepoint custom list and I'm using AngularJS to call this list. With the data I obtain from the list, I'm making a "single bar chart" for each item in this list. I'm using jquery.lineProgressbar.js to make the charts.
I'm doing the table with ng-repeat. And I need to provide a different ID name to each "chart div", otherwise the jquery.lineProgressbar.js won't work. Here's my HTML:
<table>
<tr>
<td>Name</td>
<td>Productivity percentage</td>
</tr>
<tr ng-repeat="item in items">
<td>{{item.Name}}</td>
<td>
<!-- The "ng-attr-id" provides the div a different ID depending the name they introduce. i.e.: "chart-Person1" -->
<div ng-attr-id="{{'chart-' + item.Name}}" data-percentage="{{item.Productivity_x0020_percentage}}"></div>
</td>
</tr>
</table>
and my main problem, the SCRIPT:
<script>
//I need to call each chart, one by one like this:
chartFunction('chart-Person1');
chartFunction('chart-Person2');
chartFunction('chart-Person3');
chartFunction('chart-Person4');
//and I need to make this automatically,
//because people will submit new items whenever they want,
//and I can't be updating the script each time someone uploads something.
function chartFunction(elementID) {
var dataPercentage = $("#" + elementID).data('percentage');
//this calls the chart code
$("#" + elementID).LineProgressbar({
//it says that the div selected will have a "percentage" equals to the percentage they wrote in the list.
percentage: dataPercentage
});
}
</script>
I have a Plunker. It is a little different because it has a function which runs the charts only when they're in the viewport, and it doesn't use AngularJS. But it's only so you can see how it works: my Plunker
So, as I said in my code, I need to call each new element added to the sharepoint list, but I can't be creating new calls in my code each time someone uploads an item. Thanks in advance for your help.
I've found the solution to this.
I needed to do it directly in the call of the list (in the Angular code).
<script>
var myApp = angular
.module('myApp', [])
.controller('myController', function ($scope, $http) {
//first I call the Sharepoint List with AngularJS
$http({
method: 'GET',
url: "SiteURL/_api/web/lists/getByTitle('Employees List')/items?$select=*",
headers: { "Accept": "application/json;odata=verbose" }
}).then(function onSuccess(response) {
//If the call is successful I create an empty Array called "peopleArray"
//Here I will store the names of the divs which will run the chart's code
$scope.items = response.data.d.results;
var theItems = $scope.items,
peopleArray = [];
//I run a loop to go through all the items in the Sharepoint list
//I assign a name for each person in the "peopleArray"
for(var i=0; i<theItems.length; i++) {
var currentItem = theItems[i];
peopleArray.push('chart-' + currentItem.Name);
};
//I run another loop, this one goes through the "peopleArray"
//each item executes the function below with the div name assigned in the previous loop
for(var z=0; z<peopleArray.length; z++) {
chartFunction(peopleArray[z]);
}
//and this is the function to make the charts for each person
function chartFunction(elementID) {
var dataPercentage = $("#" + elementID).data('percentage');
$("#" + elementID).LineProgressbar({
percentage:dataPercentage
});
}
}).catch(function onError(response) {
//In case of Error, it will pop an alert
alert("Error! The charts can't be loaded.");
});
});
</script>
Would just like to get and set different attributes when a list item is moved to the other list on my mvc page... I can't access anything so far. The problem is in the javascript, it hits the onchange event fine. I didnt post the "available list" in the cshtml for brevity. this is what the console.log as the bottom reads:
SpecialNeedInActiveList change: Meds per tube newIndex: -1 oldIndex: 5 action: remove
SpecialNeedActiveList change: Meds per tube newIndex: 3 oldIndex: -1 action: receive
Any help would be appreciated, this has taken way too long for me.
HTML:
<div class="col-md-6" id="SpecialNeedContainerLL">
<ul id="SpecialNeedActiveList" class="col-md-6">
#if (Model.SelectedSpecialNeeds.Any())
{
foreach (var y in Model.SelectedSpecialNeeds)
{
<li class="list-item" selected-personspecialneed="#y.PersonSpecialNeedId" selected-need-type="#y.SpecialNeedTypeId"> #y.SpecialNeedDescription </li>
}
}
</ul>
</div>
#(Html.Kendo().Sortable()
.For("#SpecialNeedActiveList")
.ConnectWith("#SpecialNeedInActiveList")
.PlaceholderHandler("placeholder")
.Events(events => events.Change("onChange"))
)
Javascript:
function onChange(e) {
var id = e.sender.element.attr("id"),
text = e.item.text(),
newIndex = e.newIndex,
oldIndex = e.oldIndex;
if (id == 'SpecialNeedActiveList' && newIndex > -1) {
//add item to selected list
//remove item from availables list
/*NONE of the following works...*/
//var oldPersonSpecialNeedId = e.sender.element.getAttribute('available-personspecialneed');
//var oldSpecialNeedTypeId = e.sender.element.getAttribute('available-need-type');
//e.sender.element.removeAttribute('available-personspecialneed');
//e.sender.element.removeAttribute('available-need-type');
//e.sender.element.setAttribute('selected-personspecialneed', oldPersonSpecialNeedId);
//e.sender.element.setAttribute('selected-need-type', oldSpecialNeedTypeId);
}
console.log(id + " change: " + text + " newIndex: " + newIndex + " oldIndex: " + oldIndex + " action: " + e.action);
}
When you are in the change event handler(onChange()), e.sender.element is NOT the item that was dragged, it is the list that sent the change event, the <ul> element.
The item being drag/dropped is contained in the e.item field, which you should be able to manipulate as normal, for example using jQuery(but you may use whatever DOM manipulation technique you like):
var $item = $(e.item);
var oldPersonSpecialNeedId = $item.attr('selected-personspecialneed');
var oldSpecialNeedTypeId = $item.attr('selected-need-type');
$item.attr("selected-personspecialneed", "new" + oldPersonSpecialNeedId);
$item.attr("selected-need-type", "new" + oldSpecialNeedTypeId);
Here's a working example showing the attributes being changed:http://dojo.telerik.com/#Stephen/arUpO
It is based on single list from the code in your question rather than 2 lists but it simply demonstrates how to access the dragged element from the sortable change event, which is the core of your problem.
Having said that, I would probably investigate using a DataSource-bound list so that you can manipulate fields of a model instead of attributes of a DOM element. http://demos.telerik.com/aspnet-mvc/sortable/integration-listview is a good place to start.
I am trying to find the order of the items as they are dragged over to the new column. I am updating the column that the item lives in once its dragged over with AJAX. I am also getting everything in order with $(this).sortable('serialize'). when I put that into an alert. The problem I am having though is when I send the array to PHP, one of the items gets dropped in the list. I am guessing it has something to do with the way I am using serialize but I am not sure. Any help I can get would be greatly appreciated. Co-workers tell me I should just accept the limits of the code and live with it. I disagree and know that the order the item is placed is almost as important as what column the data lives in. I'm thinking I need two different events in the javascript. One for the drag between lists and one in case the user rearranges items that are in the div. Hoping someone can point me in the right direction.
The HTML I have
<div class="col-lg-12 text-center">
<div class="col-md-3">
<h3>Unsorted Items</h3>
<ul id="UNSORTED" class="connectedSortable">
<li id="item-1">Unsorted item 1 from DB</li>
<li id="item-2">Unsorted item 2 from DB</li>
<li id="item-3">Unsorted item 3 from DB</li>
<li id="item-4">Unsorted item 4 from DB</li>
<li id="item-5">Unsorted item 5 from DB</li>
</ul>
</div>
<div class="col-md-3">
<h3>ACCEPTED</h3>
<ul id="ACCEPTED" class="connectedSortable">
<li id="item-6">Unsorted item 6 from DB</li>
<li id="item-7">Unsorted item 7 from DB</li>
<li id="item-8">Unsorted item 8 from DB</li>
</ul>
</div>
<div class="col-md-3">
<h3>REJECTED</h3>
<ul id="REJECTED" class="connectedSortable">
<!-- empty to show drag to -->
</ul>
</div>
</div>
The Javascript
<script>
$(function() {
$( "#UNSORTED, #ACCEPTED, #REJECTED" ).sortable({
connectWith: ".connectedSortable",
receive: function(event, ui) {
// The position where the new item was dropped
var newIndex = ui.item.index();
var sender = ui.sender.context.id;
var receiver = this.id;
var idNum = ui.item.context.id;
var display_order = $(this).sortable('serialize');
//this alerts the correct order
alert(display_order);
//this when uncommented alerts what item tranfered to and from
//alert(idNum + ' Was Transfered from "' + sender + '" to "' + receiver + '".');
//this tell the new order of the items the item was dragged to
//alert(receiver + ' Order is ' + $(this).sortable('serialize'));
var action = 'update_selection';
$.ajax({
url: "index.php?action=" + action + "&item=" + idNum + "&selection=" + receiver + '&item-' + display_order,
success:function (data) {
$("#results").html(data).slideDown('2000');
}
});
},
stop: function (event, ui) {
var sender = this.id;
var data = $(this).sortable('serialize');
//this when uncommented alerts new order of old list
//alert(sender + ' Order is ' + data);
//this was to write new order of old list unless I can figure out how to write it in the 'receive' event
/*$.ajax({
data: oData,
type: 'POST',
url: '/your/url/here'
});*/
}
}).disableSelection();
});
</script>
Shortened version of PHP
$item_id = filter_input(INPUT_GET, 'item');
/*the number after item- is dynamic from the DB and I was unable to get serialize to work without the item- in it so now I am removing item- to get the actual DB id with preg_replace */
$item_id = preg_replace('/^item-/', '', $item_id);
$selection = filter_input(INPUT_GET, 'selection');
//can't use filter_input on an array
$display = $_GET['item'];
/*this dumps the array with an array item missing. Sometimes its the first item in the array and sometimes its not */
var_dump($display);
Okay I figured it out. I needed to pass the AJAX with POST and not GET. BUT, I was still having a problem with the way I was doing it because I cannot do it the way I was doing it. I was intending on having a table that just had the display orders for each column. But that's pretty dumb when in the item table there is already a column name that the item belongs to. Its easier to just add another column with display order that update whenever the item is moved to another column. So here is my full working code which updates with AJAX and remembers where in the new column the item was placed. If anyone ever comes across this post and knows a better way, please do share. I love learning from my mistakes.
The HTML
<div class="col-lg-12 text-center sortable">
<div class="col-md-3">
<h3>Unsorted Items</h3>
<!--I am not including the PHP loop to display the list of items -->
<ul id="UNSORTED" class="sort-list">
<li id="item-1">Unsorted item 1 from DB</li>
<li id="item-2">Unsorted item 2 from DB</li>
<li id="item-3">Unsorted item 3 from DB</li>
<li id="item-4">Unsorted item 4 from DB</li>
<li id="item-5">Unsorted item 5 from DB</li>
</ul>
</div>
<div class="col-md-3">
<h3>ACCEPTED</h3>
<ul id="ACCEPTED" class="sort-list">
<li id="item-6">Unsorted item 6 from DB</li>
<li id="item-7">Unsorted item 7 from DB</li>
<li id="item-8">Unsorted item 8 from DB</li>
</ul>
</div>
<div class="col-md-3">
<h3>REJECTED</h3>
<ul id="REJECTED" class="sort-list">
<!-- empty to show drag to -->
</ul>
</div>
</div>
The Javascript
<script>
$(function(){
/* Sort steps */
$('.container').sortable({
axis: "y",
update: function (event, ui) {
var data = $(this).sortable('toArray');
$("#result").html("JSON:<pre>"+JSON.stringify(data)+"</pre>");
}
});
/* Here we will store all data */
var myArguments = {};
function assembleData(object,arguments)
{
var data = $(object).sortable('toArray'); // Get array data
var step_id = $(object).attr("id"); // Get step_id and we will use it as property name
var arrayLength = data.length; // no need to explain
/* Create step_id property if it does not exist */
if(!arguments.hasOwnProperty(step_id))
{
arguments[step_id] = new Array();
}
/* Loop through all items */
for (var i = 0; i < arrayLength; i++)
{
var image_id = data[i];
/* push all image_id onto property step_id (which is an array) */
arguments[step_id].push(image_id);
}
return arguments;
}
/* Sort images */
$('.sort-list').sortable({
connectWith: '.sort-list',
//leaves out the bootstrap class
items : ':not(.col-md-3)',
/* That's fired first */
start : function( event, ui ) {
myArguments = {}; /* Reset the array*/
},
/* That's fired second */
remove : function( event, ui ) {
/* Get array of items in the list where we removed the item */
myArguments = assembleData(this,myArguments);
},
/* That's fired thrird */
receive : function( event, ui ) {
/* Get array of items where we added a new item */
myArguments = assembleData(this,myArguments);
},
update: function(e,ui) {
if (this === ui.item.parent()[0]) {
/* In case the change occures in the same container */
if (ui.sender == null) {
myArguments = assembleData(this,myArguments);
}
}
},
/* That's fired last */
stop : function( event, ui ) {
/* Send JSON to the server */
var action = 'update_selection';
var orders = JSON.stringify(myArguments);
$.ajax({
url: 'index.php',
type: 'POST',
data: {action: action, code: orders},
//I used success function to var_dump PHP when testing
success:function (data) {
$("#result").html(data).slideDown('2000');
}
});
}
});
});
</script>
and last but not least the PHP file. I use MVC so I am calling the action and sending my script to the right case to process the PHP (Just in case someone reading this is unaware I will include that whole PHP file.)
require("classes/Db.class.php");
$db = new Db();
if (isset($_POST['action'])) {
$action = $_POST['action'];
} else if (isset($_GET['action'])) {
$action = $_GET['action'];
} else {
$action = 'home';
}
switch ($action) {
case 'home':
//gets all items and display order for those items
$unsorted = $db->query("SELECT * FROM sorting WHERE column_name = 'UNSORTED' ORDER BY display_order");
$accepted = $db->query("SELECT * FROM sorting WHERE column_name = 'ACCEPTED' ORDER BY display_order");
$rejected = $db->query("SELECT * FROM sorting WHERE column_name = 'REJECTED' ORDER BY display_order");
$possible = $db->query("SELECT * FROM sorting WHERE column_name = 'POSSIBLE' ORDER BY display_order");
include_once('home.php');
break;
case 'update_selection':
$json = filter_input(INPUT_POST, 'code'); //gets the json stringify
$array = json_decode($json, true); //specify an associative array instead of an object from json_decode
foreach($array as $key => $value){
//gets column item belongs to now
$column_name = $key;
foreach($value as $key => $number){
//this gets the key which we will use for ordering
$order = $key;
//update DB with column name item belongs to and the new order of all items in that column
$db->query("UPDATE sorting SET column_name = :column_name, display_order = :order WHERE gun_id = :number", array("column_name"=>$column_name, "number"=>$number, "order" => $order));
}
}
break;
im trying to learn Angular.
Here is what im trying to do:
I am building an App that shows me citys. When i click on a city i want to see a list of all my favourite citys.
Using an "Show-List" Button with ng-click works but requires the button the be pushed.
Here is my approach for getting it done automatic:
I want a list in my DOM automatically updated on change of the list.
$scope.$watch('updatedList', function() {
// CHECK IF WORKS
console.log($scope.updatedList);
// APPLY TO DOM
$timeout(function(){
$scope.$apply(function () {
$scope.watchList = $scope.updatedList;
});
}, 1000)
});
The Console shows no error and gives out the correc values:
Object {city.3: "Herat", city.7: "Haag", city.10: "Tilburg" ......}
In my div is the following:
<ul>
<li ng-repeat="y in updatedList">{{ y }}</li>
</ul>
<ul>
<li ng-repeat="a in watchList">{{ a }}</li>
</ul>
First for the NG-Click-Version(which works on click) second for the $scope.$watch
Sorry for lots of questions but im really struggling with the Angular-Docs.
EDIT:
Function that Adds Citys to the List:
$scope.addToList = function(name,id) {
var cityToAdd = name;
var cityToAddID = id;
// ADD A CITY TO THE COOKIE -> WORKS
$cookies.put('city.' + cityToAddID, cityToAdd);
$scope.newList = $cookies.getAll();
$scope.addToListMessage = cityToAdd + " wurde hinzugefĆ¼gt";
// Show short INFONOTICE
window.setTimeout(function() {
$scope.$apply(function() {
$scope.addToListMessage = "";
});
}, 1000);
// Update the List
$scope.updateList();
};
Second Functions -> gets Values from Cookies and puts them to an Array:
$scope.updateList = function() {
var allCitys = $cookies.getAll();
// PUT ALL INTO AN ARRAY -> WORKS
var favouritesFromCookie = [];
$.each(allCitys, function(index, value) {
if (index.indexOf('city.') == 0) { favouritesFromCookie.push(value) }
});
// PUT THE ARRAY OF CITYS INTO A SCOPE_VARIABLE
$scope.updatedList = favouritesFromCookie;
};
Your $scope.updatedList needs to be an array to be used in ng-repeat.
You shouldn't directly write a list in expression. Try this
<ul>
<li ng-repeat="y in watchList">{{ y.city }}</li>
<li ng-repeat="y in watchList">{{ y.yourListItem}}</li>
</ul>
I'm dynamically generating a list of checkboxes based on the contents of json data:
Format of tempfairway:
[{"FairWay":"A"},{"FairWay":"B"}, {"FairWay":"C"}, {"FairWay":"D"}]
var topics = tempfairway;
var topicContainer = $('ul#fairway_list');
$.each(topics, function (iteration, item) { topicContainer.append(
$(document.createElement("li")).append(
$(document.createElement("input")).attr({
id: 'topicFilter-' + item,
name: item,
value: item,
type: 'checkbox',
checked: true
})
//onclick
.click(function (event) {
var cbox = $(this)[0];
alert(cbox.value);
})
).append(
$(document.createElement('label')).attr({
'for': 'topicFilter' + '-' + item
}).text(item)
)
)
});
The checkboxes generate fine with the correct number but i'm getting [object Object] instead of the name of the fairway.
Any ideas on how to fix this?
Couple of more questions to add to this:
-What if i wanted to display ONLY unique values in tempfairway?
-.Click is set to get the value of that single checkbox, what if i want to iterate through all the checkboxes and get the value of all the ones that were selected in the case that the user unselected any of them?
In the line:
> $.each(topics, function (iteration, item) {
item is an object like {"FairWay":"A"}, so where you have:
> .text(item)
you probably want:
.text(item.FairWay)
and similarly for other uses of item. Or you could store the value in a variable and use that:
var fairwayName = item.FairWay;
...
.text(fairwayName);