How do I insert a localStorage variable into ng-repeat so the user can change the filter - angularjs-ng-repeat

Right now I have a couple of buttons that will insert a value into localStorage. I thought I could get the value and insert it into the ng-repeat line to change the filtering.
If I use plain filtering, this works:
<div class='segment' ng-repeat="x in names | filter:x.bodyType='Buggy'">
But this does not work:
<div class='segment' ng-repeat="x in names | filter:x.bodyType='<script>var show = localStorage.getItem('show'); show</script>'">
I'm not using Jquery or any other JS or CSS framework except AngularJS. Not using PHP. This is simple HTML5 for a web app.

Build the object dynamically and pass it to filter.
$scope.show = 'A';
$scope.base = function() {
return $scope.show;
};
$scope.bodyType = function() {
return {bodyType: $scope.base()};
};
$scope.objs = [{bodyType: 'A'}, {bodyType: 'B'}];
<button ng-click="show='B'">Button</button>
<div ng-repeat="x in objs | filter: bodyType()">{{x}}</div>

I don't think Angular is capable of interpolating the expression <script>...</script>. I suggest you have a function in your controller that gets the value using localStorage service like:
$scope.bodyType = function() {
localStorage.getItem('show');
};
<div class='segment' ng-repeat="x in names | filter:x.bodyType='{{bodyType()}}'">

Related

Removing ui elements from vimeo player

I want to create a simple player and remove some of the ui elements from the vimeo player, but whatever I try it doesn't work...
I have this code to load the data. At the "videoUrl" I set the params, but with no effect
But according to their documentary it should go
https://help.vimeo.com/hc/en-us/articles/360001494447-Using-Player-Parameters
<template>
// <img :src="data.thumbnail_url" alt="" #click="startVideo"/>
<div v-html="data.html" />
</template>
<script>
mounted() {
const videoUrl = `https://player.vimeo.com/video/${this.video_id}?
title=0&
byline=0&
portrait=0`
const requestUrl = `https://vimeo.com/api/oembed.json?url=${videoUrl}`
this.$axios.get(requestUrl).then((response) => {
this.data = response.data
// I also tried to create the iFrame by myself and set the params again in the src but also without any effect.
this.createIframe()
})
},
</script>
createIframe () {
const el_iframe = document.createElement('iframe')
el_iframe.setAttribute('src', `
https://player.vimeo.com/video/${this.video_id}?
title=0&
byline=0&
portrait=0
`)
}
this.$el.appendChild(el_iframe)
}
I also upgraded to a Pro account in case some of these customizations are only possible within that plan.
What I'm missing?
To set this attributes the video owner have to check this toggle button
and if you like to write the attributes in a list style, the ampersand must be in front of the attribute and the question mark in the same line with the the video-id
this.el_iframe.setAttribute('src',
`https://player.vimeo.com/video/${this.video_id}?
title=0
&byline=0
&portrait=0
`)

laravel passing a variable to js file from a controller

I have a js file located in assets folder (not View). can i pass a varible from a controller?
In view file:
The Js is called like this
<canvas id="chart1" class="chart-canvas"></canvas>
</div>
It is not possible (in my point of view) to put a variable to external JS file. You can use data-... attributes and get values from html elements.
For example you can pass your PHP variable as a json encoded string variable in your controller.
$data['chart_info'] = json_encode($chart_info);
return view('your_view', $data);
Then put it in data-info like this.
<canvas id="chart1" class="chart-canvas" data-info="{{ $chart_info }}"></canvas>
And finally in JS, you can get the variable and decode (parse) it as following.
let canvas = document.getElementById('chart1');
let info = JSON.parse(canvas.dataset.id);
console.log(info);
You can put that part of the Javascript in the view and send the variable to the same view. For example, add a section in view:
#section('footer')
<script type="text/javascript">
</script>
#endsection
Do not forget that you should add #yield('footer') to the end of your layout view.
I don't like to mix javascript and PHP/Blade, it might be hard to read the code in the future... You could use a different approach, loading the chart with a async ajax request.
You will have to create a end-point that returns the data you need for your chart:
Your router:
Route::get('/chart/get-data', [ ControllerName::class, 'getChartData' ]);
Your controller method:
public function getChartData() {
$chartData = [];
// Your logic goes here
return $chardData;
}
In your javascript (using jquery) file there will be something like that:
function loadChartData() {
$.ajax({
'url': '/chart/get-data',
'method': 'GET'
})
.done((data) => {
// Load your chart here!!!
})
.fail(() => {
console.log("Could not load chart data");
});
}
Hope I helped ;)

use parse react query results as an html tag attribute

This is my first time asking a question so I am a true SO newbie. I am currently working on a mobile app and I am using Parse React and Ratchet to build it. I have read the React documentations on FB github and apparently do not understand all enough to solve some problems. One of my problems is using the results of a Parse Query in the observe function of the declared ParseComponent as a value of a rendered react component, which in turn attempts to render the passed value as HTML. Below is the parent object:
export default class CategoryPage extends ParseComponent
{
observe(props,state){
return{
category: new Parse.Query('BusinessCategory').equalTo("objectId", this.props.categoryId)
};
}
render() {
return (
<div>
<Header text={this.data.category.objectId} back="true"/>
<div className="content">
<BusinessList categoryId={this.data.category.objectId}/>
</div>
<NavBar />
</div>
);
}
};
Notice I am passing the objectId of the category found in the Query as a text attribute of the Header React component. I am expecting Header as a child to use the passed property as follows:
var Header = React.createClass({
render: function () {
return(
<header className="bar bar-nav">
<h1 className="title">{this.props.text}</h1>
</header>
);
}
});
However the h1 is not rendering anything! I am thinking that this.data.category.objectId is a string and therefore should be rendered in the h1 tag as a string.
I do appreciate your answers very much.

How do I tell AngularJS that I've been cheating on it with jQuery?

I'm hacking together an admin interface using a pre-fab template. The navigation system that is already built uses jQuery to load content into a tag via AJAX based on window.location.hash.
If I fetch this snipped via an AJAX call and then insert it into the DOM:
<div ng-app="myApp">
{{ 2 + 2 }}
</div>
AngularJS has no idea that I've updated the DOM. The content that I see is, literally, {{ 2 + 2 }}. If I reload the page, the expression evaluates and I see the value 4 that I desire.
How do I ask AngularJS to please evaluate the content that I so brutally forced upon the DOM via non-Angularian methods?
Here's a fiddle: http://jsfiddle.net/4zRTH/
EDIT
The answer from #tasseKATT works great for simple expressions, but I'm having trouble accessing a controller. I have a NotesController that the code that I'm importing needs to access. Something more along the lines of:
<div ng-controller="NotesController">
{{ notes.length }}
</div>
I updated the fiddle so it's a little more along the lines of what I'm looking to do: http://jsfiddle.net/5Xhs9/4/
You need to use $apply:
$apply() is used to execute an expression in angular from outside of
the angular framework. (For example from browser DOM events,
setTimeout, XHR or third party libraries). Because we are calling into
the angular framework we need to perform proper scope life cycle of
exception handling, executing watches.
In your example however the app is not even bootstrapped, so you need to:
1) Select the element:
var dynamicContent = "<div id='someId' ng-app> {{ 2 + 2 }} </div>";
$('.expression').html(dynamicContent);
var element = angular.element(document.querySelector('#someId'));
2) Bootstrap it:
angular.bootstrap(element, []);
3) Retrieve the scope:
var elementScope = element.scope();
4) Call $apply:
elementScope.$apply();
Demo: http://jsfiddle.net/5Xhs9/
Edit for new scenario:
In your new example you have added ng-app"myApp" to an existing div, so AngularJS will bootstrap your application for you, and now you want to dynamically add this content instead:
<div id='notes' ng-controller='NotesController'> {{ notes.length }} </div>
You have already defined the NotesController and added it to the module. What you now can do is:
1) Retrieve the $injector service:
var $injector = angular.element(document.querySelector('.container')).injector();
2) Use the $injector to compile the newly added element and link it to its scope. Call $apply:
var element = angular.element(document.querySelector('#notes'));
$injector.invoke(function($compile) {
var scope = element.scope();
$compile(element)(scope);
scope.$apply();
});
Demo: http://plnkr.co/edit/P6VwLee6AUWO7aDT601m?p=preview
You can cheat by saving $compile and $rootScope in the app.run function on window: http://plnkr.co/edit/pxGhof1zD0rZknagfmyc?p=preview
window.compileForAngular = null;
window.rootScope = null;
var app = angular.module('jQuery', []);
app.run(function ($compile, $rootScope) {
window.rootScope = $rootScope;
window.compileForAngular = $compile;
doNotTryThisAtHome();
});
function doNotTryThisAtHome() {
// let's just pretend that this came in over an AJAX request
var dynamicContent = "<div> {{ 2 + 2 }} </div>";
// I insert it into the DOM via jQuery
$('.expression').html(window.compileForAngular(dynamicContent)(window.rootScope));
}
http://jsfiddle.net/QC97L/2/
See the above fiddle
// Code goes here
jQuery(document).ready(function () {
// let's just pretend that this came in over an AJAX request
var dynamicContent = "<div id='mainApp' > {{ 2 + 2 }} </div>";
// I insert it into the DOM via jQuery
$('.expression').html(dynamicContent);
var app = angular.module('myApp',[])
angular.bootstrap('#mainApp',['myApp']);
// now how do I get AngularJS to evalulate the expression?
});

How to update a label from a postback in MVC3/Razor

MVC/Razor/Javascript newbie question:
I have a MVC3/Razor form where the use can select a single product from a drop down list.
<div class="editor-label">
Product
</div>
<div class="editor-field">
#Html.DropDownList("ProductID", (IEnumerable<SelectListItem>)ViewBag.Products, "--Select One--")
#Html.ValidationMessageFor(model => model.ProductID)
</div>
What I then want is to display the price of the selected product on a label just below the drop down list (model property name is Amount).
This should be pretty easy, but I am pretty new at Razor, and know almost nothing about Javascript, so I would appreciate any verbose explanations of how do do it, and how it all hangs together.
Add a div/span under the Dropdown .
#Html.DropDownList("ProductID", (IEnumerable<SelectListItem>)ViewBag.Products, "--Select One--")
<div id="itemPrice"></div>
and in your Script, make an ajax call to one of your controller action where you return the price.
$(function(){
$("#ProductId").change(function(){
var val=$(this).val();
$("#itemPrice").load("#Url.Action("GetPrice","Product")", { itemId : val });
});
});
and have a controller action like this in your Product controller
public string GetPrice(int itemId)
{
decimal itemPrice=0.0M;
//using the Id, get the price of the product from your data layer and set that to itemPrice variable.
return itemPrice.ToString();
}
That is it ! Make sure you have jQuery loaded in your page and this will work fine.
EDIT : Include this line in your page to load jQuery library ( If it is not already loaded),
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
The Amount isn't available to your view when the user selects a product (remember the page is rendered on the server, but actually executes on the client; your model isn't available in the page on the client-side). So you would either have to render in a JavaScript array that contains a lookup of the amount based on the product which gets passed down to the client (so it's available via client-side JavaScript), or you would have to make a callback to the server to retrieve this information.
I would use jQuery to do this.
Here's a simple example of what the jQuery/Javascript code might look like if you used an array.
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$(document).ready(function() {
// This code can easily be built up server side as a string, then
// embedded here using #Html.Raw(Model.NameOfPropertyWithString)
var list = new Array();
list[0] = "";
list[1] = "$1.00";
list[2] = "$1.25";
$("#ProductID").change(displayAmount).keypress(displayAmount);
function displayAmount() {
var amount = list[($(this).prop('selectedIndex'))];
$("#amount").html(amount);
}
});
</script>
<select id="ProductID" name="ProductID">
<option value="" selected>-- Select --</option>
<option value="1">First</option>
<option value="2">Second</option>
</select>
<div id="amount"></div>
You'll want to spend some time looking at the docs for jQuery. You'll end up using it quite a bit. The code basically "selects" the dropdown and attaches handlers to the change and keypress events. When they fire, it calls the displayAmount function. displayAmount() retrieves the selected index, then grabs the value out of the list. Finally it sets the HTML to the amount retrieved.
Instead of the local array, you could call your controller. You would create an action (method) on your controller that returned the value as a JsonResult. You would do a callback using jquery.ajax(). Do some searching here and the jQuery site, I'm sure you'll find a ton of examples on how to do this.

Resources