Passing a reverse route as a JavaScript parameter in Scala Play - ajax

I'm using reverse routing within AJAX to call an Action from a controller in my view:
<script>
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("toolOptions").innerHTML =
this.responseText;
}
};
xhttp.open("GET", "#routes.MyController.loadTemplate2()", true);
xhttp.send();
}
</script>
and my controller at app.controllers.MyController has a method:
def loadTemplate2() = Action {
implicit request: Request[AnyContent] => Ok(views.html.template2())
}
Which is routed like:
GET /mycontroller/retrieve2 controllers.MyController.loadTemplate2
And when I hardcode the route like this and call it from somewhere in the template like <li onclick="loadDoc()">Load Template 2</li>, it works as expected and loads the template 2. However, this method is useful, and I want to be able to parameterize the URL called by the xhttp.open, so I want to replace
function loadDoc() with function loadDoc(myURL) and
xhttp.open("GET", "#routes.MyController.loadTemplate2()", true); with
xhttp.open("GET", myUrl, true);
And then be able to call other methods I may have, say:
def loadTemplate3() = Action {
implicit request: Request[AnyContent] => Ok(views.html.template2())
}
From somewhere else in the template from a <li> like:
<li onclick="loadDoc(#routes.MyController.loadTemplate2())">Load Template 2</li>
<li onclick="loadDoc(#routes.MyController.loadTemplate3())">Load Template 3</li>
But when I do this, it doesn't work. The console tells me
SyntaxError: invalid regular expression flag d
I've also tried to do this instead
<li onclick="loadDoc(#routes.MyController.loadTemplate2())">Load Template 2.absoluteURL(true)</li>
But this tells me SyntaxError: missing ) after argument list[Learn More] in the console. The error message points to a line in the header of the generated HTML (1:13), which doesn't make any sense - there aren't ANY "()"'s up there . But I've changed nothing else and can't spot any missing ')' anywhere. I feel like I'm close, but can't quite get it.

I simplified this question over here, and the answers are taken from two of the responders:
There are two issues. I am trying to pass a String literal, and the
#routes.MyController.loadTemplate2()
Turns into something like this in the rendered HTML /theUrl/toTheServer
Problem is, starting something with / is indication that you're going to use a Regex.
Change this:
<li onclick="loadDoc(#routes.MyController.loadTemplate2())">Load Template 2</li>
to
<li onclick="loadDoc('#routes.MyController.loadTemplate2()')">Load Template 2</li>
or
<li onclick="loadDoc("#routes.MyController.loadTemplate2()")">Load Template 2</li>

Related

Laravel 9 pass model object into view

I am trying to pass a model object into view and use it in JS, but I can't make it work. It looks broken and throws a syntax error Uncaught SyntaxError: Unexpected token '&' if I just use the variable.
I tried using compact() but this does not work aswell compact(): Argument #1 must be string or array of strings, App\Models\Quiz given
Here is how I return the view with the object:
$result = Quiz::where('id', $quiz_id)->first();
if (!$result['active'] || $result['hidden_by_admin']) {
return abort(404);
}
$result['classic_questions'] = ClassicQuestion::where('quiz_id', $quiz_id)->with('classic_answers')->get();
$result['quiz_tags'] = QuizHasTags::where('quizzes_id', $quiz_id)->with('quiz_tag')->get();
return view('play_quiz')->with('quiz', $result);
Here is how I want to access it in blade.php:
<script>
const quiz = {{ $quiz }};
console_log(quiz);
</script>
Assign your data into the window global object which will make it
available everywhere and you can access it from your JS file:
<ul>
#foreach ($quiz as $quiz_data)
<li> {{ $quiz_data }} </li>
#endforeach
</ul>
<script type="text/javascript">
window.data = {!! json_encode($quiz) !!};
</script>
<script src="...."></script>
// trying to access the model $data from the view.
$(function() {
var values = window.data;
alert(values);
}
You can also send data to view like this:
In controller:
return view('play_quiz', $result);
In view
foreach($quiz_tags as quiz){
//code
}

Post/Get Methode with href and list-group-iteam

I try to build a post/get method with an list group team / href. Here is my code...
#if(count($variableController) > 0)
<ul class="list-group">
#foreach($variableController as $variableView)
{{$variableView->heimmannschaft}}
#endforeach
</ul>
#endif
spielerAuswahl is my view. And after a click on the list-group-item I get to this view. But there I need the information from the list-group-item.
Route::post('/spielerAuswahl', function () {
return 123;
//var_dump($_POST)
});
What I have to do?
replcae post with get method like this:
Route::get('/spielerAuswahl', function () {
return 123;
//var_dump($_POST)
});
if you want to return spielerAuswahl as view
Route::get('/spielerAuswahl', function () {
return view('spielerAuswahl');
});
dont forget
spielerAuswahl.blade.php should be in reousrces/view directory
on the other hand if you want to send some data to view
change route to :
Route::get('/spielerAuswahl/{somevar}', function ($somevar) {
return view('spielerAuswahl',compact('somevar'));
});
and send data like this:
#if(count($variableController) > 0)
<ul class="list-group">
#foreach($variableController as $variableView)
{{$variableView->heimmannschaft}}
#endforeach
</ul>
#endif
it was get method
if you want to use post method your action method should be POST
one way is using <form action="" method="post">

Angular-JS. How to make controllers work inside ng-repeat with ng-show

I am very new at Angular and I am trying to make something where if you click a tab, ng-repeat will show everything with a certain property and if you click a different tab, ng-repeat witll show everything with a different property. However I cant get the tab controller to work along with ng-show. Here is my code:
<ul class = "nav nav-pills" ng-controller = "TabController as tabCtrl">
<li ng-class="{'active':tabCtrl.isTab(1)}">
<a ng-click="tabCtrl.setTab(1)" href = "#"> All </a>
</li>
<li ng-class="{'active':tabCtrl.isTab(2)}">
<a ng-click="tabCtrl.setTab(2)" href = "#"> Online </a>
</li>
<li ng-class="{'active':tabCtrl.isTab(3)}">
<a ng-click="tabCtrl.setTab(3)" href="#"> Offline </a>
</li>
</ul>
...
<div class = "user" ng-repeat="streamer in twitch.users" ng-show="tabCtrl.isTab(1)">
//... repeated stuff here
</div>
Here is the js code for TabController:
app.controller('TabController', function(){
this.tab = 1;
this.setTab = function(t){
this.tab = t;
}
this.isTab = function(t){
return (this.tab == t);
}
})
However ng-show shows nothing as isTab() is always false. Can anyone explain to me why?
Use the pattern I referred to in the comments to keep a reference to the controller object. This is how you might do it using the "controller as" syntax in AngularJS:
app.controller('TabController', function(){
var self = this;
this.tab = 1;
this.setTab = function(t){
// inside a function "this" is not the controller
// it is a reference to the function
self.tab = t;
};
this.isTab = function(t){
return (self.tab == t);
};
})

Autoclosing unclosed tags in template

Hi i'm tring to create such template
<script type='text/mustache' id='user-template'>
<ul>
{{#each users}}
<li>{{name}}</li>
{{#startHidden #index 2}}</ul><ul style = "display:none;">{{/startHidden}}
{{#endHidden #index 2}}</ul>show all{{/endHidden}}
{{/each}}
</ul>
</script>
So the idea is to close the upper <ul> after second user in list open new hidden <ul> and put all rest users here. But instead i got closed <ul> and final html looks like:
<ul>
<li>name1</li>
<li>name2</li>
<ul style="display:none;"></ul>
<li>name3</li>
<li>name4</li>
show all
</ul>
This is my js
var data = [{name: "name1"},{name: "name2"},{name: "name3"},{name: "name4"}];
var users = new can.List(data);
var frag = can.view("user-template",{users:users},{
'startHidden' : function(currentIndex, usersToShow, options){
if (currentIndex() === usersToShow-1) {
return options.fn(this);
}
},
'endHidden' : function(currentIndex, usersToShow, options){
var length = options.scope.attr('users').length;
if ((length>usersToShow)&&(currentIndex() === length-1)) {
return options.fn(this);
}
}
});
Is there any way to prevent auto closing tags, or may i'm just doing it wrong completely?
This is not possible. can.view.live.html can only remove or add elements in sequence. A workaround would be to just add a "hidden" class on an LI if it shouldn't be visible.

Highlight Current Menu Item Using Prototype JS

The challenge is to set current menu item as active in magento, which uses Prototype JS and not JQuery.
<ul id="mainmenu">
<li>home</li>
<li><a id="menuItem" href="{{store url='our-cakes'}}">Our Cakes</a></li>
<li>About us</li>
<li>Outlets</li>
<li>Franchise</li>
<li>contact us</li>
</ul>
<script type="text/javascript">// <![CDATA[
document.observe("dom:loaded", function() {
$(mainmenu).childElements().each(function(e){
var h = e.down('a').readAttribute('href');
if(h == window.location){
e.addClassName("current");
}
});
});
// ]]></script>
Here's a refinement of that method. Note that depending on the browser, the href of a link and the window.location.href may have a substring match, but not a full match, because of the rest of the URL which the browser provides from context. Just == is not going to make it.
var here = $$('#mainmenu a').sortBy(function(a){
return a.href.length;
}).reverse().find(function(a){
return window.location.href.include(a.href);
});
if(here) here.up().addClassName('current');
Also, this is looking for the longest match first, so you don't get all of the menu items highlighted on the home link /.

Resources