how can i compare class to a string in js - javascript

I want to add toggle star functionality in my project. For which I'm calling this script on click. This code fails to compare value of starclass to the class defined in the string.
Here i m trying to add star/unstar functionality just like gmail messages to my project.
$(".mailbox-star").click(function (e) {
debugger;
e.preventDefault();
var $this = $(this).find("a > i");
var glyph = $this.hasClass("glyphicon");
var fa = $this.hasClass("fa");
var msgId = $("#MsgId").val();
var StarClass = $(".mailbox-star i").attr('class');
var StarStatus;
if (StarClass === "fa text-yellow fa-star-o") {
StarStatus = true;
} else {
StarStatus = false;
}
//var starstatus = document.getElementById('ReadstatusStarred');
if (glyph) {
$this.toggleClass("glyphicon-star");
$this.toggleClass("glyphicon-star-empty");
}
$.ajax({
url: "/Home/Starred",
type: "GET",
dataType: "json",
data: {
ChangeStarredStatus: StarStatus,
ChangeMessageId: msgId
},
success: function (status) {
if (status) {
alert(status);
if (fa) {
$this.toggleClass("fa-star");
$this.toggleClass("fa-star-o");
}
}
},
error: function () {
alert("starfailed1");
}
})
});
//HTML CODE
here i m fetching values from my controller using model .If I can send value of IsStarred parameter in my js code my problem will be sorted
<table class="table table-hover table-striped">
<tbody>
#{int count = 0;}
#foreach (var item in Model)
{
string[] dt = #item.DateTime.ToString().Split(' ');
<tr title="#item.DateTime" id="ReadMessage" class="#((item.IsRead != true) ? "row row-highlight" : "row")" >
<td><input type="hidden" value="#item.IsRead" id="Readstatus_#count"></td>
<td><input type="hidden" value="#item.IsStarred" id="ReadstatusStarred"></td>
<td><input type="hidden" id="MsgId" value="#item.MessageId" /></td>
<td><input type="checkbox"></td>
<td class="mailbox-star" ><i class="#((item.IsStarred==true)? "fa fa-star text-yellow":"fa text-yelow fa-star-o")"></i></td>
<td class="mailbox-name" id="Text1" onclick="location.href='#Url.Action("Read", "Home", new
{
NameRead = item.FullName,
SubjectRead = item.Subject,
BodyRead = item.Body,
DateRead = item.DateTime,
MessageIdRead= item.MessageId,
})'">
<a href="#" id="Name">
#item.FullName
</a>
</td>
<td class="mailbox-subject" id="Text1">
<b>#item.Subject</b>-
#if (item.Body == null || item.Body.Length == 0)
{
}
else
{
if (item.Body.Length >= 100)
{
#item.Body.Substring(0, 100)
}
else
{
#item.Body
}
}
</td>
<td class="mailbox-attachment"></td>
<td class="mailbox-date">
#dt[0]
</td>
</tr>
count++;
}
</tbody>
</table>
</div>

Try using jQuery's is() to check for classes instead
var StarStatus = $(".mailbox-star i").is('.fa, .text-yellow, .fa-star-o')

If I got your description right you wanna have something like gmail has, click to star a mail, click again to destar it?
It's hard to say what is broken without the HTML you are using but I would do this in the following manner:
When loading mails from back you have to set up class "starMarked" to starred mails depending on how you mark the starred mail in the data comming from back you would check if something is true or equal to some value and then .addClass("starMarked") to that element.
bind the .click(Function that does the logic below) to all elements that represent mail (list member, square, icon, depends on what you have in the UI)
A functionality of that click then checks if that mail is stared or not. Since the status is already represented with class no need to check through data pulled from the server or make an additional request to the server to get that email's status. This saves time and load on the server.
NOTE: You must be certain the request to change status on the server went through or your logic of toggling on front and status on backend might become inconsistent!
Toggle on front could be done numerous ways but simplest would be using the CSS class "starMarked" to represent it's starred and lack of it to signal it's not. It gives 2 birds with one stone (looks and logic). If you need to check the status you could use .hasClass("starMarked").
When toggling a class use .removeClass() to remove the class from the element

Related

How do I pass a list of models from a table in a view to a controller?

I'm just learning about MVC and a problem I've run into is passing a list of models to a controller. I have AutomationSettingsModel, which contains a list of AutomationMachines. I've successfully populated a table in my view with checkboxes bound to data in AutomationMachines. However, passing the data to a method in the controller is turning out to be harder than I expected.
Here is my view with the first attempt at passing the data:
#model FulfillmentDashboard.Areas.Receiving.Models.Automation_Settings.AutomationSettingsModel
<div class="container-fluid px-lg-5">
#using (Html.BeginForm("Index", "ReceiverSettings", "get"))
{
<div>
<h2>Receiving Automation Settings</h2>
<br>
<table id="machineSettings" class="table">
<tr>
<th>Automation Machine Name</th>
<th>Divert Line Setting </th>
</tr>
#if (Model.AutomationMachines != null && Model.AutomationMachines.Count > 0)
{
foreach (var item in Model.AutomationMachines)
{
<tr>
<td> #Html.DisplayFor(x => item.Name) </td>
<td> #Html.CheckBoxFor(x => item.DivertSetting) </td>
</tr>
}
}
</table>
<div class="row">
<input class="btn btn-primary" type="button" value="Save"
onclick="location.href='#Url.Action("UpdateDivertSettings", "ReceiverSettings", new { models = #Model.AutomationMachines } )'" />
</div>
</div>
}
</div>
This resulted in UpdateDivertSettings being hit in my controller, but the data was null. After some searching, it looks like I will need to use Ajax, which I am unfamiliar with. I tried following the example at this site, which resulted in the following addition to the view:
<input type="button" id="btnSave" value="Save All" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script type="text/javascript">
$("body").on("click", "#btnSave", function () {
//Loop through the Table rows and build a JSON array.
var machines = new Array();
$("#machineSettings TBODY TR").each(function () {
var row = $(this);
var machine = {};
machine.Name = row.find("TD").eq(0).html();
machine.DivertSetting = row.find("TD").eq(1).html();
machines.push(machine);
});
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
url: "/ReceiverSettings/UpdateDivertSettings",
data: JSON.stringify(machines),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
alert(r + " record(s) inserted.");
}
});
});
</script>
However that never seemed to hit UpdateDivertSettings in the controller. Some more searching resulting in the idea of serializing my AutomationSettingsModel and passing that via Ajax, but I'm not really sure how to do that. It also looks like I can do something using Ajax.BeginForm, but I can't figure out how I would structure the new form. So I'm trying to get some input on the easiest way to get this data to my controller.
Edit:
Here is the controller as it currently stands:
namespace FulfillmentDashboard.Areas.Receiving.Controllers
{
[RouteArea("Receiving")]
public class ReceiverSettingsController : BaseController
{
private readonly AutomationService automationService;
public ReceiverSettingsController(AutomationService _automationService)
{
automationService = _automationService;
}
[Route("ReceiverSettings/Index")]
public async Task<ActionResult> Index()
{
var refreshedView = await automationService.GetAutomationSettings( new AutomationSettingsModel(ActiveUserState.ActiveIdSite) );
refreshedView.AutomationMachineIdSite = ActiveUserState.ActiveIdSite;
return View("Index", refreshedView);
}
public async Task<ActionResult> UpdateDivertSettings(List<AutomationMachineModel> machines)
{
//foreach (AutomationMachineModel machine in machines)
//{
// var results = await automationService.UpdateAutomationSettings(machine, ActiveUserState.IdUser);
//}
return Json(new { #success = true });
}
}
}

Button within modal's table not firing [duplicate]

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 3 years ago.
Attempted to put a delete button that works in a table into a modal, with a table and it's like the click event is not firing at all. Hit's not back end code, no console.log(s), or js break points. Am I missing something?
Modal's Table
<table class="table table-hover table-md ">
<thead>
<tr>
<td class="text-left TableHead">Role</td>
<td class="text-right TableHead">Delete</td>
</tr>
</thead>
#*--Table Body For Each to pull DB records--*#
<tbody>
#foreach (var role in Model.Roles)
{
<tr>
<td>#role</td>
<td>
<button class="sqButton btnRed float-right zIndex"
title="Delete" data-toggle="ajax-modal" data-target="#deleteRoleUser"
data-url="#Url.Action("Delete", "Administration",
new {Id = Model.Id , Type = "roleUser"})" >
<i class="glyphicon glyphicon-remove"></i>
</button>
</td>
</tr>
}
</tbody>
</table>
Controller that it's supposed to call
[HttpGet]
public async Task<IActionResult> Delete(string id, string type)
{
if (type == "user") {
ViewBag.Type = "user";
var user = await userManager.FindByIdAsync(id);
if (user == null)
{
ViewBag.ErrorMessage = $"User with Id = {id} cannot be found";
return View("NotFound");
}
var model = new EditUserViewModel
{
Id = user.Id,
UserName = user.UserName,
};
ViewBag.UN = user.UserName;
return PartialView("~/Views/Modals/_DeleteModalPartial.cshtml", model);
}
if (type == "roleUser")
{
ViewBag.Type = "roleUser";
var role = await roleManager.FindByIdAsync(id);
if (role == null)
{
ViewBag.ErrorMessage = $"Role with Id = {id} cannot be found";
return View("NotFound");
}
var model = new EditRoleViewModel
{
Id = role.Id,
RoleName = role.Name,
};
ViewBag.Role = role.Name;
return PartialView("~/Views/Modals/_DeleteModalPartial.cshtml", model);
}
else
{
ViewBag.ErrorMessage = $"cannot be found";
return View("NotFound");
}
}
I am not sure why the click event on the button is not working at all. I have tried removing random code and literally nothing is making it go over to the controller at the least.
EDIT added javascript
$(function () {
var placeholderElement = $('#modal-placeholder');
$('[data-toggle="ajax-modal"]').click(function (event) {
var url = $(this).data('url');
$.get(url).done(function (data) {
placeholderElement.html(data);
placeholderElement.find('.modal').modal('show');
});
});
});
$('.sqButton').click( function (event) {
event.stopPropagation();
});
Since the button doesn't exist on page load you will have to create a event delegate to something that does exist on page load that will attach the event to the right element when it finally does appear in the DOM
In this case we will use the document (because it always exists on page load, some people use 'body') to delegate the event to the [data-toggle="ajax-modal"], like this:
$(document).on('click', '[data-toggle="ajax-modal"]', function (event) {
// code here
});
This will attach the event to the [data-toggle="ajax-modal"] elements on page load AND after page load if the element gets added later.
Try replacing your javascript code
$('.sqButton').click( function (event) {
event.stopPropagation();
});
With the following code
$('.sqButton').click(function(event) {
var url = $(this).data('url');
$.get(url).done(function (data) {
placeholderElement.html(data);
placeholderElement.find('.modal').modal('show');
});
});
if you manually force click, does it hit your controller?
document.querySelector('.btnRed').click();
is there any other element(s) "hijacking" click event?

How to filter data on screen with ajax using dropdown list? [duplicate]

In a MVC partial view file, I build one Html.TextBox and two submit buttons. These two buttons will increase/decrease the Html.TextBox value once clicked. The Html.TextBox displayed value will change accordingly.However, once I need to update the #refTable div based on the new value after click. The page or section never updated. Codes are below, where some comments are added for explanation purpose. Thanks for your help.
//******* cshtml file **********//
<body>
</body>
<input type="submit" value="PrevY" name="chgYr2" id="pY" />
#{
var tempItem3 = Model.First(); // just give the first entry from a database, works.
if (ViewData["curSel"] == null)
{
#Html.TextBox("yearSelect3", Convert.ToDateTime(tempItem3.Holiday_date).Year.ToString());
ViewBag.selYear = Convert.ToDateTime(tempItem3.Holiday_date).Year; // just initial value, works
ViewData["curSel"] = Convert.ToDateTime(tempItem3.Holiday_date).Year;
}
else
{
#Html.TextBox("yearSelect3", ViewData["curSel"].ToString());
}
}
<input type="submit" value="NextY" name="chgYr2" id="nY" />
<script type="text/javascript">
$(document).ready(function () {
$(document).on("click", "#nY", function () {
var val = $('#yearSelect3').val();
$('#yearSelect3').val((val * 1) + 1);
var dataToSend = {
id: ((val * 1) + 1)
}
// add some jquery or ajax codes to update the #refTable div
// also ViewBag.selYear need to be updated as ((val * 1) + 1)
// like: ViewBag.selYear = ((val * 1) + 1);
// any similar temp variable is fine
});
});
$(document).on("click", "#pY", function () {
var val = $('#yearSelect3').val();
$('#yearSelect3').val((val * 1) - 1);
var dataToSend = {
id: ((val * 1) - 1)
}
});
});
</script>
<span style="float: right">Set Holiday Calender for 2013</span>
<span id="btnAddHoliday">#Html.ActionLink("Add Holiday", "Create", null, new { id = "addHilBtn" })</span>
<div id="refTable">
<table class="tblHoliday" style="width: 100%;">
<th>
Holiday
</th>
<th>
Dates
</th>
<th>Modify</th>
<th>Delete</th>
</tr>
#foreach (var item in Model)
{
if ( Convert.ToDateTime(item.Holiday_date).Year == ViewBag.selYear)
// if the ViewBag.selYear is hard code, this selection "works"
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Holiday_Name)
</td>
<td>
#item.Holiday_date.Value.ToString("MM/dd/yyyy")
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { })
</td>
<td>
#Html.ActionLink("Delete", "Delete", new { })
</td>
</tr>
}
}
</table>
</div>
You'll need AJAX if you want to update a part of your page without reloading the entire page.
main cshtml view
<div id="refTable">
<!-- partial view content will be inserted here -->
</div>
#Html.TextBox("yearSelect3", Convert.ToDateTime(tempItem3.Holiday_date).Year.ToString());
<button id="pY">PrevY</button>
<script>
$(document).ready(function() {
$("#pY").on("click", function() {
var val = $('#yearSelect3').val();
$.ajax({
url: "/Holiday/Calendar",
type: "GET",
data: { year: ((val * 1) + 1) }
})
.done(function(partialViewResult) {
$("#refTable").html(partialViewResult);
});
});
});
</script>
You'll need to add the fields I have omitted. I've used a <button> instead of submit buttons because you don't have a form (I don't see one in your markup) and you just need them to trigger javascript on the client side.
The HolidayPartialView gets rendered into html and the jquery done callback inserts that html fragment into the refTable div.
HolidayController Update action
[HttpGet]
public ActionResult Calendar(int year)
{
var dates = new List<DateTime>() { /* values based on year */ };
HolidayViewModel model = new HolidayViewModel {
Dates = dates
};
return PartialView("HolidayPartialView", model);
}
This controller action takes the year parameter and returns a list of dates using a strongly-typed view model instead of the ViewBag.
view model
public class HolidayViewModel
{
IEnumerable<DateTime> Dates { get; set; }
}
HolidayPartialView.csthml
#model Your.Namespace.HolidayViewModel;
<table class="tblHoliday">
#foreach(var date in Model.Dates)
{
<tr><td>#date.ToString("MM/dd/yyyy")</td></tr>
}
</table>
This is the stuff that gets inserted into your div.
The main concept of partial view is returning the HTML code rather than going to the partial view it self.
[HttpGet]
public ActionResult Calendar(int year)
{
var dates = new List<DateTime>() { /* values based on year */ };
HolidayViewModel model = new HolidayViewModel {
Dates = dates
};
return PartialView("HolidayPartialView", model);
}
this action return the HTML code of the partial view ("HolidayPartialView").
To refresh partial view replace the existing item with the new filtered item using the jQuery below.
$.ajax({
url: "/Holiday/Calendar",
type: "GET",
data: { year: ((val * 1) + 1) }
})
.done(function(partialViewResult) {
$("#refTable").html(partialViewResult);
});
You can also use Url.Action for the path instead like so:
$.ajax({
url: "#Url.Action("Holiday", "Calendar", new { area = "", year= (val * 1) + 1 })",
type: "GET",
success: function (partialViewResult) {
$("#refTable").html(partialViewResult);
}
});

MVC Client-Side Validation for EditorFor in foreach

So I have a view with the following structure (this isn't the actual code, but a summary):
#using (Html.BeginForm("Action", "Controller", FormMethod.Post))
{
#Html.ValidationSummary("", new { #class = "text-danger" })
<table>
<thead>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody id="myTableBody">
#for (int i = 0; i < Model.Components.Count; i++)
{
#Html.EditorFor(m => m.MyCollection[i])
}
</tbody>
<tfoot>
<tr>
<td>
<button id="btnAddRow" type="button">MyButton</button>
</td>
</tr>
</tfoot>
</table>
<input type="button" id="btnSubmit" />
}
#section scripts {
#Scripts.Render("~/Scripts/MyJs.js")
}
The EditorFor is rendering markup that represents rows bound to properties in MyCollection. Here's a sample snippet of how the editor template looks:
#model MyProject.Models.MyCollectionClass
<tr>
<td>
#Html.TextBoxFor(m => m.Name)
</td>
<td>
#Html.DropDownListFor(m => m.Type, Model.AvailableTypes)
</td>
</tr>
Basically, my problem is that the client-side validation won't fire for the elements inside of the editor template as it should. Could someone point me in the right direction of where I might be going wrong with this.
Also, please note that the following is set in my web.config.
<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
and also MyCollectionClass has proper [Require] annotations on the properties that shall be enforced. Another thing to note is that checking
if(ModelState.IsValid)
{
}
Returns false, as expected, if the required fields aren't right. The problem there is that I want client-side validation and not server-side. One of my other pages is implementing jQuery validation, but does not contain all the nesting that this scenario does and thus it works correctly.
Thanks in advance.
From what I Have learnt MVC Doesn't really provide 'out of the box' client side validation.
there are third party options but I prefer to do my own thing so I handballed the whole thing in JavaScript.
To compound matters with the EditorFor doesn't allow adding html attributes like other Helper Methods.
My Fix for this was fairly complex but I felt comprehensive, I hope you find it as helpful as I have
First Overload the HtmlHelper EditorFor in .Net
public static HtmlString EditBlockFor<T, TValue>(this HtmlHelper<T> helper, Expression<System.Func<T, TValue>> prop, bool required)
{
string Block = "";
Block += "<div class='UKWctl UKWEditBox' " +
"data-oldvalue='" + helper.ValueFor(prop) + "' " +
"data-required='" + required.ToString() + ">";
Block += helper.EditorFor(prop);
Block += "</div>";
return new HtmlString(Block);
}
add the new editBlockfor in razor view (just as you are) but alter the Begin Form method to add a Name and id to the form element so you can identify it later
#using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { name = "MyDataForm", id = "MyDataForm" }))
Then when the User Clicks Save, Run the validation method from JavaScript
function validate(container) {
var valid = true;
//use jquery to iterate your overloaded editors controls fist and clear any old validation
$(container).find(".UKWctl").each(function (index) { clearValidation($(this)); });
//then itterate Specific validation requirements
$(container).find(".UKWctl[data-required='True']").each(function (index) {
var editobj = getUKWEdit(this);
if (editobj.val() == "") {
valid = false;
//use this Method to actually add the errors to the element
AddValidationError(editobj, 'This field, is required');
//now add the Handlers to the element to show or hide the valdation popup
$(editobj).on('mouseenter', function (evt) { showvalidationContext(editobj, evt); });
$(editobj).on('mouseout', function () { hidevalidationContext(); });
//finally add a new class to the element so that extra styling can be added to indicate an issue
$(editobj).addClass('valerror');
}
});
//return the result so the methods can be used as a bool
return valid;
}
Add Validation Method
function AddValidationError(element, error) {
//first check to see if we have a validation attribute using jQuery
var errorList = $(element).attr('data-validationerror');
//If not Create a new Array()
if (!errorList || errorList.length < 1) {
errorList = new Array();
} else {
//if we have, parse the Data from Json
var tmpobj = jQuery.parseJSON(errorList);
//use jquery.Map to convert it to an Array()
errorList = $.map(tmpobj, function (el) { return el; });
}
if ($.inArray(error, errorList) < 0) {
// no point in add the same Error twice (just in case)
errorList.push(error);
}
//then stringyfy the data backl to JSON and add it to a Data attribute on your element using jQuery
$(element).attr('data-validationerror', JSON.stringify(errorList));
}
Lastly Show and hide the actual Errors,
In order to facilitate this easily I slipped in a little div element to the _Layout.html
<div id="ValidataionErrors" title="" style="display:none">
<h3 class="error">Validation Error</h3>
<p>This item contatins a validation Error and Preventing Saving</p>
<p class="validationp"></p>
</div>
Show
var tipdelay;
function showvalidationContext(sender, evt)
{
//return if for what ever reason the validationError is missing
if ($(sender).attr('data-validationerror') == "") return;
//Parse the Error to an Object
var jsonErrors = jQuery.parseJSON($(sender).attr('data-validationerror'));
var errorString = '';
//itterate the Errors from the List and build an 'ErrorString'
for (var i = 0; i <= jsonErrors.length; i++)
{
if (jsonErrors[i]) {
//if we already have some data slip in a line break
if (errorString.length > 0) { errorString += '<br>'; }
errorString += jsonErrors[i];
}
}
//we don't want to trigger the tip immediatly so delay it for just a moment
tipdelay = setTimeout(function () {
//find the p tag tip if the tip element
var validationError = $('#ValidataionErrors').find('.validationp');
//then set the html to the ErrorString
$(validationError).html(errorString);
//finally actually show the tip using jQuery, you can use the evt to find the mouse position
$('#ValidataionErrors').css('top', evt.clientY);
$('#ValidataionErrors').css('left', evt.clientX);
//make sure that the tip appears over everything
$('#ValidataionErrors').css('z-index', '1000');
$('#ValidataionErrors').show();
}, 500);
}
Hide (Its much easier to hide)
function hidevalidationContext() {
//clear out the tipdelay
clearTimeout(tipdelay);
//use jquery to hide the popup
$('#ValidataionErrors').css('top', '-1000000px');
$('#ValidataionErrors').css('left', '-1000000px');
$('#ValidataionErrors').css('z-index', '-1000');
$('#ValidataionErrors').hide();
}
for usage you can try some thing like
function save()
{
if (validate($("#MyDataForm")))
{
$("#MyDataForm").submit();
}
else {
//all the leg has been done this stage so perhaps do nothing
}
}
here is My Css for the validation Popup
#ValidataionErrors {
display: block;
height: auto;
width: 300px;
background-color: white;
border: 1px solid black;
position: absolute;
text-align: center;
font-size: 10px;
}
#ValidataionErrors h3 { border: 2px solid red; }
.valerror { box-shadow: 0 0 2px 1px red; }

Infinite scrolling fills completely rather than incrementally

I am attempting to create infinite scrolling on my web page using an example I found. However, the page fills up completely with all the items instead of just showing several items at a time. In other words it is not doing infinite scrolling. I noticed in some of the examples they parsed out data in chunks but in the real world how are you supposed to do that?
Below is my html code:
<table class="table table-striped table-bordered"><tr>
<th style="text-align:center;">User ID</th> <th>Username</th><th>Rank</th>
<th>Posts</th><th>Likes</th> <th>Comments</th> <th>Flags</th><th>Status</th><th>Action</th></tr>
<tr><td class="center">
<div ng-app='scroll' ng-controller='Scroller'>
<div when-scrolled="loadMore("")">
<div ng-repeat='item in items'>
<span>{{item.id}}
<span style="position:absolute;left:140px;">{{item.username}}</span>
<span style="position:absolute;left:290px;">{{item.rank}}</span>
<span style="position:absolute;left:360px;">{{item.posts}}</span>
<span style="position:absolute;left:440px;">{{item.likes}}</span>
<span style="position:absolute;left:530px;">{{item.comments}}</span>
<span style="position:absolute;left:640px;">{{item.flags}}</span>
<span class="label label-success" style="position:absolute;left:710px;">Active</span>
<a style="position:absolute;left:790px;" class="btn btn-info" style="width:30px" ng-href='/admin/userDetail?userid={{item.id}}'>
View Detail</a>
<hr>
</div>
</div>
</div>
</td></tr>
</table>
Below is my angularjs code:
function Scroller($scope, $http, $q, $timeout) {
$scope.items = [];
var lastuser = '999999';
$scope.loadMore = function(type) {
todate = document.getElementById("charttype").value;
var url = "/admin/getusers?type=" + todate + "&lastuser=" + lastuser;
var d = $q.defer();
$http({
'url': url,
'method': 'GET'
})
.success(function (data) {
var items = data.response;
for (var i = $scope.items.length; i < items.length; i++) {
$scope.items.push(items[i]);
count++;
if (count > 100)
{
lastuser = $scope.items[i].id;
break;
}
d.resolve($scope.items);
d.promise.then(function(data) {
});
}
)
.error(function (data) {
console.log(data);
});
return d.promise;
};
$scope.loadMore();
}
angular.module('scroll', []).directive('whenScrolled', function() {
return function(scope, elm, attr) {
var raw = elm[0];
alert("scroll");
elm.bind('scroll', function() {
if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
scope.$apply(attr.whenScrolled);
}
});
};
});
My question is why does my web page show all 3200 lines initially rather than allowing me to do infinite scrolling. You will notice I put an alert in the scroll module and it is never displayed. Do I have to incrementally read my database? Any help is appreciated.
You are adding all of the items returned from your API call into $scope.items.
for (var i = 0; i < items.length; i++) {
$scope.items.push(items[i]);
}
Don't you want to add only a subset of those items?
P.S. Might help if you create a Plunkr to show the specific problem.
EDIT:
Based on your comment about the directive not working, I put together this Plunkr, which is a copy of your code but with the $http get code ripped out. The "scroll" alert fires here. I think you're just missing a closing bracket on your for loop (since I don't have your API endpoint to test against, I can't actually run your code live).
EDIT 2:
I'm not sure why you aren't seeing the function fire correctly on scroll. I've set up another plunker where I've changed the result of the scroll event firing to show an alert and load more items from a data variable, so you can see that the scroll event is firing correctly and it will load more items.

Categories