I'm trying to set a Knockout-bound function's parameter with Razor. I've tried...
<a href="#" data-bind="click: function() { return myFunc(#Type.SomeType.ToString()); }">
Click Me
</a>
and..
<a href="#" data-bind="click: function() { return myFunc(#Html.Raw(Type.SomeType.ToString())); }">
Click Me
</a>
and..
<a href="#" data-bind="click: function() { return myFunc('#Html.Raw(Type.SomeType.ToString())'); }">
Click Me
</a>
and..
<a href="#" data-bind="click: function() { return myFunc('#(Html.Raw(Type.SomeType.ToString()))'); }">
Click Me
</a>
Is there a right way to do this?
(Background: this is for use in a bootstrap dropdown)
You can try to surround data-bind attribute with single quotes (') and pass the parameter using Json.Encode.
Full example:
#{
// A string with a lot of special characters
string myStr = "abc\"\\/'#{}#.:xyz";
}
<span data-bind='click: function() { myFunc(#Json.Encode(myStr)); }'>
Click Me
</span>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-debug.js"></script>
<script>
ko.applyBindings({
myFunc: function (myParam) {
console.log(myParam);
}
});
</script>
In your case it would be:
<a href="#" data-bind='click: function() { return myFunc(#Json.Encode(Type.SomeType.ToString())); }'>
Click Me
</a>
Related
I have two views and each view contains an link with data-action attribute to call jQuery function called toggle menu like this:
<div id="hide-menu" class="btn-header pull-right">
<span>
<a href="javascript:void(0);" class="toggleMenu" data-action="toggleMenu" title="Collapse Menu")">
<i class="fa fa-reorder"></i>
</a>
</span>
</div>
jQuery:
toggleMenu: function () {
if (!$.root_.hasClass("menu-on-top")) {
$('html').toggleClass("hidden-menu-mobile-lock");
$.root_.toggleClass("hidden-menu");
$.root_.removeClass("minified");
} else if ($.root_.hasClass("menu-on-top") && $.root_.hasClass("mobile-view-activated")) {
$('html').toggleClass("hidden-menu-mobile-lock");
$.root_.toggleClass("hidden-menu");
$.root_.removeClass("minified");
}
}
one of the views calls the function properly but the another doesn't, What is the possible reason for that??
in fact I haven't known the actual reason of the issue, maybe as Ramesh said in the comments was the problem.
I solved it by putting the function in the same document (not in another js file) and in the element, I have used onClick attribute to execute the function.
<div id="hide-menu" class="btn-header pull-right">
<span>
<a href="javascript:void(0);" class="toggleMenu" onclick="toggle()" title="Collapse Menu">
<i class="fa fa-reorder"></i>
</a>
</span>
</div>
<script>
function toggle() {
if (!$.root_.hasClass("menu-on-top")) {
$('html').toggleClass("hidden-menu-mobile-lock");
$.root_.toggleClass("hidden-menu");
$.root_.removeClass("minified");
} else if ($.root_.hasClass("menu-on-top") && $.root_.hasClass("mobile-view-activated")) {
$('html').toggleClass("hidden-menu-mobile-lock");
$.root_.toggleClass("hidden-menu");
$.root_.removeClass("minified");
}
}
</script>
I have a button/img in LI. I want to when clicked change css and text-decoration underline.
Ts file :
onSelect(i: number) {
var element = document.getElementsByClassName('brand')[i];
const elementClass = element.className;
if (elementClass != 'btn brand selected') {
this.renderer.addClass(element,'selected');
}
else{
this.renderer.removeClass(element,'selected');
}
}
HTML file :
<li class="nav-item" *ngFor="let brand of brands let i = index">
<button class="btn brand" id="brand" type="button" data-toggle="showCategory" aria-controls="tabOne"
data-target="#tabOne" href="#merk1" (click)="getCategories(brand.id); onSelect(i);">
<img [src]="brand.imageLink" width="100" height="40" [alt]="brand.name" role="button">
</button>
</li>
The simplest solution could be using [ngClass] directive with some logic rather than getting the DOM element and manipulating it.
// declare a variable to which assign the selected brand index
selectedBrand: number;
In template assign the current selected index
<li class="nav-item" *ngFor="let brand of brands let i = index">
<button class="btn brand" (click)="getCategories(brand.id); selectedBrand=i"> <=== NOTE this
<img [src]="brand.imageLink" width="100" height="40" [ngClass]="{'selected': selectedBrand === i}"> <=== You can assign any class if the current index and selected index is matched
</button>
</li>
Hope this works with you
controller:
.controller('BlogController', function(blogFactory, $routeParams, $scope){
var that=this;
stat=false;
this.checkbookmark = function(bId){
console.log(bId)
blogFactory.checkBookmark(bId, function(response){
console.log(response)
if(response == "bookmarked"){
that.stat = true;
}
else{
that.stat = false;
}
})
}
html code:
<div class="container" ng-controller="BlogController as blogCtrl">
<div class="row" ng-repeat="chunk in blogCtrl.blogs | filter: filter_name | orderBy:'-created_at' | groupBy: 3">
<div class="outerbox1 col-sm-4" ng-repeat="blog in chunk" >
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog._id)">
<br>
<div> > READ MORE
<a ng-if="blogCtrl.stat" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blogCtrl.stat}}</a>
<a ng-if="!blogCtrl.stat" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blogCtrl.stat}}</a>
</div>
</div>
</div>
</div>
</div>
I want to show glyphicon based on the value of stat
I have 6 blogs, first 3 are bookmarked and next 3 are not.
The problem i'm getting is that the stat value is always set according to the last bookmark and hence it is always false / true (based on the condition of last blog).
How to resolve this?
Instead of setting the stat property on the controller you should set the property on the blog object (it obviously belongs to the object)
Replace your checkbookmark function with this:
this.checkbookmark = function(blog){ //pass the entire blog, not just the id
blogFactory.checkBookmark(blog._id, function(response){
console.log(response)
if(response == "bookmarked"){
blog.stat = true; //set the property on blog instead of the controller
}
else{
blog.stat = false;
}
})
}
And then use it like this:
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog)">
<br>
<div> > READ MORE
<a ng-if="blog.stat" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blog.stat}}</a>
<a ng-if="!blog.stat" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blog.stat}}</a>
</div>
</div>
You will need to make similar changed to your add and removebookmark functions
I'm having trouble figuring out how to have dynamic data only update when the user selects from the typeahead menu or clicks the search button.
Right now, the dynamic content pertaining to the search query updates automatically when the input value is changed (content disappears). I want the content to stay in view until a new selection has been either clicked in the typeahead list or clicked by the search button.
Any insight at all would be greatly appreciated! Thank you!
Plunker demo:
http://plnkr.co/edit/jVmHwIwJ0KOKCnX6QjVa?p=preview
Code:
<!-- HTML -->
<body ng-controller="MainController">
<!-- Search -->
<div class="well">
<p>Search the term "content"</p>
<form role="form">
<div class="form-group clearfix search">
<input type="text" ng-model="selectedContent" ng-options="query as query.searchQuery for query in searchData" bs-typeahead="bs-typeahead" class="form-control search-field"/>
<button type="button" class="btn btn-primary search-btn"><span class="glyphicon glyphicon-search"></span></button>
</div>
</form>
</div>
<!-- Dynamic Content -->
<div class="well">
<h4>{{ selectedContent.contentTitle }}</h4>
<ul>
<li ng-repeat="item in selectedContent.headlines">{{item.headline}}</li>
</ul>
</div>
<!-- typeahead template -->
<ul class="typeahead dropdown-menu" tabindex="-1" ng-show="$isVisible()" role="select">
<li role="presentation" ng-repeat="match in $matches" ng-class="{active: $index == $activeIndex}">
</li>
<!-- JS -->
var app = angular.module('demoApp', ['ngAnimate', 'ngSanitize', 'mgcrea.ngStrap'])
.config(function ($typeaheadProvider) {
angular.extend($typeaheadProvider.defaults, {
template: 'ngstrapTypeahead.html',
container: 'body'
});
});
function MainController($scope, $templateCache, $http) {
$scope.selectedContent = '';
$http.get('searchData.json').then(function(response){
$scope.searchData = response.data;
return $scope.searchData;
});
};
You could use a directive such as this:
app.directive('mySearch', function(){
return {
restrict: 'A',
require: 'ngModel',
link: function($scope, $element, $attrs, ngModel){
ngModel.$render = function(){
if (angular.isObject($scope.selectedContent)) {
$scope.clickedContent = $scope.selectedContent;
}
}
$scope.updateModel = function() {
$scope.clickedContent = $scope.selectedContent;
}
}
}
})
plunker
Edit:
I added using the ngModelController. The function you set ngModel.$render to gets called whenever the model updates. If you click the typahead popup, then the model selectedContent will be an object, otherwise it'll be a string. If it's an object (meaning the user clicked the typahead popup) we do the same as we did in the updateModel function.
how can i create a popup with MVC bootstrap?
I have this code, when I click on "generate password" calls to a function (it´s in my controller Admin) and it returns me a string. How can i display the string in a popup window??
<div class="editor-field" title="User Password">
<a class="btn btn-primary btn-small" href="#"
onclick="location.href='#Url.Action("GeneratePsw", "Admin", null)'; return false;">
<i class="icon-lock icon-white"></i> Generate password
</a>
</div>
Since event listeners are better than click events, I'd probably do something like this:
<div class="editor-field" title="User Password">
<a id="pwd_gen" class="btn btn-primary btn-small" href="#">
<i class="icon-lock icon-white"></i> Generate password
</a>
</div>
$(function() { // document.ready shorthand
$('#pwd_gen').click(function() {
var myPwd = $(this).location.href='#Url.Action("GeneratePsw", "Admin", null);
alert(myPwd); // or however you want to handle it with Bootstrap
});
});
$(document).on("click", ".open-ShowPwdDialogUser", function () {
var pwd="";
$.get("#Url.Action("GeneratePsw", "Admin")",function(data){
pwd=data;
$(".modal-body #pwdUser").val(pwd);
$('#1').modal('show');
});
})