I have the following custom Handlebars helper:
Handlebars.registerHelper('IsNewUser', function (userId) {
return (userId < 1);
});
And the following HTML in my view:
{{#IsNewUser Id}}
<div>
<input name="IsActive" id="user-active" type="checkbox" checked />
Active
</div>
{{/IsNewUser}}
I can clearly see the function being hit, the userId parameter passed correctly, and the return is true of type bool but instead of showing the block it shows the text 'true'.
How can I get the HTML block to hide with Handlebars without error'ing out?
I was able to fix it after gaining some insight from this StackOverflow question. Changed my helper method to the following:
Handlebars.registerHelper('IsNewUser', function (userId, options) {
if (userId < 1)
return options.fn(this);
else
return options.inverse(this);
});
Related
I have an HTML template that's stored in sql as follows
<script id="Accounttmpl" type="text/x-jsrender">
<div class="authenticated" id="authenticated" >
<span class="loginWelcome">Hi </span>
<span class="loginWelcome">{{>FirstName}}</span>
<span id="Test" style="display:none">{{>(Verified)}} </span>
</div>
</script>
So, in my code in Javascript the template above gets called. However I want to add an if statement where if verified == 'false' it must display a message saying not verified.
This is my Javascript:
Success: function (result, context) {
if (result) {
$(context).html($('#Accounttmpl').render(result));
} else {
$(context).html($('#Accounttmpl').render({}));
}
}
So, in my result I get back the "verified" details, so what I tried is the following:
Success: function (result, context) {
if (result) {
if(result.Verified === 'false'){
document.getElementById("Test").html("not verified")} //however it doesn't find the "Test" id and throws an error that it cant read property of null
$(context).html($('#Accounttmpl').render(result));
} else {
$(context).html($('#Accounttmpl').render({}));
}
}
}
So, my question is how do I check the #Accounttmpl for the "Test" id so that I can add the if statement to it?
The reason why you get null is because you are trying to get the id of Test before you add it to the DOM.
Where you have:
if(result.Verified === 'false'){
document.getElementById("Test").html("not verified")
}
$(context).html($('#Accounttmpl').render(result));
Change the order round:
$(context).html($('#Accounttmpl').render(result));
if(result.Verified === 'false'){
document.getElementById("Test").html("not verified")
}
Also, you are mixing JavaScript with jQuery here:
document.getElementById("Test").html("not verified")
Either do:
document.getElementById("Test").textContent = "not verified";
Or
$("#Test").html("not verified")
If someone has a better title feel free to edit. I inherited a project from a developer who is leaving the company and I'm scratching my head trying to find a solution to a problem the existing code provides.
Code from the view:
<div>
<table class="table">
<tr>
<th class="border-bottom border-top-0">Action</th>
</tr>
#foreach (Step actionItem in Model.Steps)
{
#if (actionItem.HasRun == false)
{
<tr class="border-top-0">
<td>
#if (actionItem.ReturnsInfo == true)
{
<input type="button" value="Run Check" onclick="loadProcessingFeedbackPartial('#actionItem.StepID', '#Model.Client.DatabaseConnectionString' )" />
}
else
{
<input type="submit" value="Run Check" name="btnRunStoredProcedure" asp-action="CallStepStoredProcedure" asp-route-StepID="#actionItem.StepID" asp-route-StepCompleted="#actionItem.HasRun" />
}
</td>
</tr>
break;
}
}
</table>
</div>
Javascript being called from the button click:
<script type="text/javascript">
function loadProcessingFeedbackPartial(x, y) {
var url = '#Url.Action("ViewProcessingFeedBackPartial", "Client")';
var stepId = x;
var databaseConnectionString = y;
$("#processingFeedbackPartialDiv").load(url, { stepId, databaseConnectionString },
function () {
$("#confirmButton").removeAttr("style");
});
}
</script>
Controller action:
public IActionResult ViewProcessingFeedBackPartial(int StepId, string DatabaseConnectionString)
{
FeedbackDetails feedbackDetails = new FeedbackDetails();
feedbackDetails.Data = _clientProcessingService.GetProcessingFeedbackDetails(StepId, DatabaseConnectionString);
return PartialView("_ViewFeedback", feedbackDetails);
}
The button in the view has an Onclick event that goes to the Javascript function, which loads a partial view with the data from the controller calling a service method. Here's where the problem is. If no rows are returned, I want to bypass the partial being drawn entirely.
So I changed the controller action around a bit to include a condition where if the feedbackDetails.Data has 0 rows to just call a different method from the service, process as normal, but return the View instead of a partial.
public IActionResult ViewProcessingFeedBackPartial(int StepId, string DatabaseConnectionString, int ClientId)
{
FeedbackDetails feedbackDetails = new FeedbackDetails();
feedbackDetails.Data = _clientProcessingService.GetProcessingFeedbackDetails(StepId, DatabaseConnectionString);
if(feedbackDetails.Data.Rows.Count == 0)
{
_clientProcessingService.RunProcessStepConfirmation(DatabaseConnectionString, StepId, ClientId, "No information returned, automatically proceeding to next step.");
return RedirectToAction("Processing", new { Id = ClientId });
}
return PartialView("_ViewFeedback", feedbackDetails);
}
This "worked", except since in the view it's being called in a Javascript function that loads a partial regardless, the view is returned inside that partial instead of the view being returned.
But I'm unsure how to fix this because without first clicking the button and attempting to populate that collection with data, I don't know if it's empty (and skip the partial) or it has rows (and draw the partial).
I attempted creating an intermediary controller action that returns a boolean and attempted to use the result of that inside the javascript function to either draw the partial or skip it based on the bool, but I'm not really the greatest at Javascript so I wasn't able to get it to work.
I'm unsure if the way to solve this involves creating logic that displays multiple buttons that route to different controller actions or javascript functions or just handling it all via Javascript somehow.
What would be a good way to go about solving this?
#Mkalafut, your jQuery function is loading the controller result directly into "#processingFeedbackPartialDiv" regardless of the result received. Better to pull this initially into a variable, then add some simple logic to decide what to do next. Potentially the controller can help by returning a null result that is easy to identify.
e.g.
$.get("url", { stepId, databaseConnectionString }, function (data) {
var result = data;
// Some example conditional logic - adjust as required
if (result != null){
$("#processingFeedbackPartialDiv").html(result);
$("#confirmButton").removeAttr("style");
}
});
Remember, jQuery load & get are both just shorthand functions for ajax, so if needs be you can customise the code further to get the flexibility you need.
https://api.jquery.com/jQuery.get/
https://api.jquery.com/load/
I just followed this
JSFiddle example to create a little search box from an array object in my javascript. Now after some tweaking and research on search.object and filter:search:strict. Now that I have it filtering correctly, I modified a checkbox in the template that is checked upon loading the document and switched on or off based on a custom data attribute in the html that is updated by the json array.
How do I run this check once someone clears the search and the old items show back up again?
In the HTML I have this template
<div ng-repeat="o in objects | filter:search:strict | orderBy:'obj_name'" class="objectContainer">
<h3>{{o.obj_name}}</h3>
<label class="userToggleSwitch" >
<input class="userToggleInput" data-isactive="{{o.obj_isactive}}" type="checkbox">
<div class="slider round"></div>
</label>
</div>
In the JS
angular.element(document).ready(function(){
angular.module('searchApp',[])
.controller('searchCtrl', ['$scope','objHolder',function ($scope,objHolder) {
$scope.search = '';
$scope.objects = [];
$scope.objects = objHolder.getobjects();
}])
// fake service, substitute with your server call ($http)
.factory('objHolder',function(){
var objects = objList;
return {
getobjects : function(){
return objects;
}
};
});
});
The JS that modifies the items on document load is using jquery like this
$(document).ready(function(){
//console.log($('.userToggleInput'));
$.each($('.userToggleInput'), function(){
if($(this).data("isactive") == 1){$(this).attr('checked', true);}
if($(this).data("isactive") == 0){$(this).attr('checked', false);}
})
$('.userToggleInput').click(function(){
if ($(this).attr('checked') == undefined) {
// THIS IS WHERE WE WILL MAKE AN AJAX CALL TO A PHP CLASS
// TO REQUEST IF THE USER CAN BE TURNED ON - DUE TO LIC RESTRICTIONS
$(this).attr('checked',true);
} else {
$(this).attr('checked',false);
}
//console.log($(this).attr('checked'));
});
});
Created JS Fiddle to assist in Helping in this manner
I'm relatively new to AngularJS and I've found myself slightly confused.
Here is my controller:
app.controller("calcController", function($scope) {
$scope.interests=[{time:'month',amount:0},
{time:'quarter',amount:0},
{time:'year',amount:0}];
$scope.rates=[{rate:0.01,lower:0,upper:1000,desc:'£0 - £1000'},
{rate:0.02,lower:1000,upper:5000,desc:'£1000 - £5000'},
{rate:0.03,lower:5000,upper:'none',desc:'£5000+'},];
$scope.balance=0;
$scope.updatedIntAmount=function(balance){
if(balance<0){
return 0;
}
else if(balance>=rates[1].lower && balance<rates[1].upper){
return balance*rates[1].rate;
}
else if(balance>=rates[2].lower && balance<rates[2].upper){
return balance*rates[2].rate;
}
else {
return balance*rates[3].rate;
}
}
});
What I want is some way to bind the value of interests.amount to updatedIntAmount.
Here's my HTML:
<div ng-controller="calcController" class="container">
<div class="form-group">
<label for="balInput">Balance:</label>
<input id="balInput" type="text" class="form-control" ng-model="balance">
</div>
<p ng-repeat="interest in interests">{{'per '+interest.time+':'+interest.amount}}</p>
</div>
So what I have is interests.amount dependent on calculateIntAmount, which in turn is dependent on both rates.rate and balance. How can I get these interests.amount values to change whenever balance is updated?
Thanks
Try adding ng-change to your input field like so <input id="balInput" type="text" class="form-control" ng-model="balance" ng-change="updatedIntAmount(balance)">. This will allow you to call the function on a change to the input field and thus do whatever you want within the function in your controller.
You can learn more at the official AngularJS documentation page
You can look into using $scope.$watch to observe any changes in your balance variable, and then update your interests.amount accordingly.
In your controller, you would have:
$scope.$watch('balance', function(newBalance) {
$scope.interests.amount = $scope.updatedIntAmount(newBalance);
});
Lot of errors are present in your code.
as first there is nothing like rates[1] instead you should change it to $scope.rates[1].
Second : your updatedIntAmount function contains rates[3] which is again wrong as you have rates[2] as max limit according to array index rule.
Your updatedIntAmount function return a single value based upon the balance is inserted. in that case after correcting the errors just add :
{{updatedIntAmount(balance)}}
in your html code. it will change as soon as change in balance.
$scope.updatedIntAmount=function(balance){
if(balance<0){
return 0;
}
else if(balance>=$scope.rates[0].lower && balance<$scope.rates[0].upper){
return balance*$scope.rates[0].rate;
}
else if(balance>=$scope.rates[1].lower && balance<$scope.rates[1].upper){
return balance*$scope.rates[1].rate;
}
else {
return balance*$scope.rates[2].rate;
}
}
I have a requirement of a search page in which I am using KendoUI grid to display the search result.
I have a textbox and button and if text is entered and on click event of button I hace to display the grid with the list of users matching to search result.
I am using ASP.net MVC and KENDOUI grid.
My View:
The search box and button:
<div id="SearchSection">
<input type="text" id="txtSearch" class="k-textbox"/>
<button class="k-button"id="btnSearch" style="width:150px">Search</button>
</div>
The KendoUI grid
<div id="ADUserSection">
<div id="ADSearchedUser">
List of users in Active directory:
<div id="ADuserGrid">
#(Html.Kendo().Grid<ADUser>()
.Name("kADUser")
.Columns(columns =>
{
columns.Bound(p => p.UserLoginName);
columns.Bound(p => p.UserDisplayName);
})
.AutoBind(false)
.DataSource(ds =>
{
ds.Ajax()
.Read(read =>
{
read.Action("GetADUser", "ManageUsers")
.Data("AdditionalData");
});
})
)
)
</div>
</div>
My JavaScript Function:
<script>
$(document).ready(function () {
$("#ADUserSection").fadeOut(0);
$("#AvailableUserRoleSection").fadeIn()
});
var enterTest
$("#btnSearch").click(function () {
debugger;
enterTest = $("#txtSearch").val().trim();
if (enterTest == "") {
$("#ADUserSection").fadeOut();
}
else {
AdditionalData();
$("#ADUserSection").fadeIn();
var grid = $("kADUser").data("kendoGrid").dataSource.read({ searchText: enterTest });
//**Breaks at this Point**//
}
});
function AdditionalData() {
//$("#ADuserGrid").empty();
$("#ADuserGrid").fadeIn();
return {
searchText: enterTest
}
}
My Controller Action
public JsonResult GetADUser([DataSourceRequest] DataSourceRequest request, string searchText)
{
viewmodel.searchedADUser = model.GetUserFromAD(searchText);
return Json(viewmodel.searchedADUser.ToList().ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
On the button click event in javascript when I attach the grid to event I get the error the datasource read is not recognised.
Exact error is:
JavaScript runtime error: Unable to get property 'dataSource' of undefined or null reference
Please help me in that. any idea please share or if I am doing anything wrong in my above code please point out.
I am very new to KendoUi and MVC so please elaborate n yur explanation.
I got the above problem becosue of missing # before the grid name.
But Now I habe one more issue, even though I am follwing all the proper step.
In my above AdditionalData javascript function my parameter is not getting set set in the paaremeter
function AdditionalData() {
//$("#ADuserGrid").empty();
$("#ADuserGrid").fadeIn();
return {
searchText: enterTest
}
}
This searchText is not getting set even tough I am getting value in enterTest.
Any help will be of very great use. I am really stuck in this.
You're trying to access your grid with:
var grid = $("kADUser").data("kendoGrid");
$("kADUser") won't find any elements, because it's looking for a kADUser tag, and the .data() of an empty jQuery set is null.
As a result, when you try to access grid.dataSource, grid is "undefined or null" (which is what the error is telling you).
You should be using an id selector:
var grid = $("#kADUser").data("kendoGrid");
In general, I'd suggest to avoid compound statements and keep it at one statement per line. This will make debugging much easier.