I want to be able to use a Stimulus Controller in multiple places in a web app. I want do something like this:
<div data-controller="mycontroller">
<OneComponent />
</div>
<SomeOtherComponent />
<div data-controller="mycontroller">
<NewComponent />
</div>
But the controller just seem to connect to the first Component and not in the second. Is it possible to use it as I'm intending to?
Thanks!
Stimulus controllers can be reused. See this sample.
Possible problems that may prevent this from working is if there is a JS error, or that you expect elements in nested components to be used in the parent component, if they have not been rendered yet.
const application = Stimulus.Application.start()
application.register("hello", class extends Stimulus.Controller {
connect() {
console.log("connect to", this.element.getAttribute("data-language"))
}
static get targets() {
return [ "name" ]
}
greet() {
if (this.element.getAttribute("data-language") == "es-ES") {
console.log(`¡Hola, ${this.nameTarget.value}!`);
} else {
console.log(`Hello, ${this.nameTarget.value}!`);
}
}
})
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="https://unpkg.com/stimulus/dist/stimulus.umd.js"></script>
</head>
<body>
<div data-controller="hello" data-language="en-US">
<input data-hello-target="name" type="text" value="John">
<button data-action="click->hello#greet">Greet</button>
</div>
<div data-controller="hello" data-language="es-ES">
<input data-hello-target="name" type="text" value="Jose">
<button data-action="click->hello#greet">Saudar</button>
</div>
</body>
</html>
Related
Right so my codes for my test view is:
#Secured(["IS_AUTHENTICATED_REMEMBERED", "IS_AUTHENTICATED_FULLY"])
def list(){
def allPosts = postService.getPosts()
}
<body>
<h1>Welcome to the main feed, <sec:loggedInUserInfo field="username" var="username"/></h2>
<g:if test="${flash.message}">
<div class="messageContainer">
<div style="display: block">${flash.message}</div>
</div>
</g:if>
<p/>
<div>
<g:each var="post" in="${allPosts}">
<p>Last Name: ${post.content}</p>
<p>First Name: ${post.content}</p>
</g:each>
</div>
</body>
</html>
And this works,
This was just to test if there was another issue though as what I want it to work on is this:
#Secured(["IS_AUTHENTICATED_REMEMBERED", "IS_AUTHENTICATED_FULLY"])
def wall() {
def allPosts = postService.getPosts()
profile = springSecurityService.currentUser.getProfile()
if(!profile){
redirect(controller: "profile", action: "viewProfile")
}else {
[profile: profile]
}
}
and
<!doctype html>
<html>
<head>
<meta name="layout" content="main"/>
</head>
<body>
<h1>Welcome to the main feed, <sec:loggedInUserInfo field="username" var="username"/></h2>
<g:if test="${flash.message}">
<div class="messageContainer">
<div style="display: block">${flash.message}</div>
</div>
</g:if>
<p/>
<div>
<h3>
What are you thinking?
</h3>
</p>
<div>
<g:form action="addPost">
<g:textArea class="postContent" id="postContent" name="content" rows="3" cols="50"/><br/>
<g:submitButton class="postSubmit loginButton" name="post" value="Post"/>
</g:form>
<div>
</div><br/>
<div class="PostContainer">
<g:each var="post" in="${allPosts}">
<p>${post.content}</p>
<p>${post.content}</p>
</g:each>
</div>
</div>
</body>
</html>
but the posts and content will not render on the second example
also the postService:
#Transactional
class PostService {
def getPosts() {
[allPosts:Post.list()]
}
}
Any insight into this would be greatly appreciated.
I am using windows 10 and chrome for the browser
Try to return from the service in this way
#Transactional
class PostService {
def getPosts() {
Post.list()
}
}
I have a situation where i wish to render 2 partial views in single layout.cshtml one below another. Each partial view belongs to separate controller. I processed it using 2 different approach, the first one which i wanted it to work didn't worked out.
What i wanted it is to have partial view controller of categoris1 (see div-id below in layout.cshtml) and then below it display partial view of categoris2 div.
let's say this is my _Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - ABCD</title>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap-theme.min.css" rel="stylesheet" />
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
#Html.ActionLink("TitleName", "Index", "Files", new { area = "" }, new { #class = "navbar-brand" })
</div>
</div>
</div>
<div class="row panel">
//My first view should be displayed here
<div id="categoris1" class="col-lg-3">
#Html.Action("DispatchedProducts", "DispatchedProducts")
</div>
//Second view should be displayed here just below first one
<div id="categoris2" class="col-lg-3">
#Html.Action("DisplayUnDispatchedProducts", "UnDispatchedProducts")
</div>
<div class="col-lg-8">
#RenderBody()
</div>
<hr />
<footer>
<p>© #DateTime.Now.Year - My MVC Application</p>
</footer>
</div>
</body>
</html>
This results in displaying of the categoris1 div controller view only when i run application (but not categoris2 partialview)and categoris2 div partial view is displayed at other url (when i write path to controller and view in browser) and what i wanted it is to display on same page just below categoris1 .
My next approach which worked was i just kept this categoris2 div (line below) in the partial view of 'DispatchedProducts' at the bottom of DisplayDispatchedProducts.cshtml and it displayed exactly what i expected.
<div id="categoris2" class="col-lg-3">
#Html.Action("DisplayUnDispatchedProducts", "UnDispatchedProducts")
</div>
Complete DisplayDispatchedProducts.cshtml something like this:
#model IList<ABC.Models.Product>
#{
ViewBag.Title = "First view";
}
<div class="col-md-10">
<h2>Dispatched Items</h2>
<div class="form-group">
<label class="col-md-2 control-label">Dispatched Items</label>
<table>
#foreach (var item in Model)
{
<tc>
<td>
<img src=#item.ProdUrl height="100" width="100" />
</td>
</tc>
}
<hr />
</table>
</div>
</div>
and DisplayDispatchedProducts controller has method like this (similar is other controller and partial view with same return types but different queries) :
public PartialViewResult DisplayDispatchedProducts()
{
productDispatched = uow.ProductsRepository.GetProductWithOrder().ToList();
return PartialView(productDispatched);
}
But i want to move with the first approach to have call to both partial views in just _Layout.cshtml file like i mentioned above. Which i expected to display both in a row below each other. Is it feasible to happen ? How to make it work ?
Please let me know if any other info needed
Have you tried calling Html.RenderPartial or Html.RenderAction?
RenderPartial(String partialViewName)
RenderAction(String actionName, String controllerName, Object routeValue)
There are other overrides for each of these methods depending on which version of the framework you are using.
I tried lot,googling even took help from laracast.com/discuss but could not solve the issue. why the session flash is not working? please drop your suggestion. Here is my code of all_controll.php
<?php
namespace App\Http\Controllers;
use DB;
use App\Quotation;
use App\Model\students;
use Illuminate\Http\Request;
//use Auth;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests;
use App\Http\Controllers\Session;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;
class all_control extends Controller
{
public function index()
{
return view('index');
}
public function insert_students(Request $request)
{
$std = new students();
$std->name = $request->input('name');
$std->email = $request->input('email');
$std->save();
return redirect('/index');
}
public function getform()
{
return view('form');
}
public function postform()
{
$roll = Input::get('roll');
$ct_number = Input::get('ct');
DB::table('test')->insert(array(
'name' => $roll,
'age' => $ct_number
));
Flash :: Session ("key",
"You have done successfully!!!!");
//Session::flash('message','You have done successfully!!!!');
return Redirect::route('getform');
//return redirect('/index');
}
}
and my form.blade.php code is given below
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
<meta charset="UTF-8">
<meta name=description content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" media="screen">
</head>
<body>
<div class="container">
<h1>Form</h1>
<h3>
<?php
if(Session::has('key')){
echo Session::get('key');
}
?>
</h3>
<form action="{{ URL::route('postform') }}" method="post" role="form">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<legend>Form Title</legend>
<div class="form-group">
<label for="">name</label>
<input type="text" class="form-control" name="roll" id="roll" placeholder="Input...">
</div>
<div class="form-group">
<label for="">Marks of Physisc CT</label>
<input type="number" class="form-control" name="ct" id="ct" placeholder="Input...">
</div>
<button type="submit" class="btn btn-primary">Hit the Button</button>
</form>
</div>
</body>
</html>
You can use the built in redirect() helper which will flash the data to the session by using ->with().
public function postform(Request $request)
{
$roll = $request->roll;
$ct_number = $request->ct;
DB::table('test')->insert([
'name' => $roll,
'age' => $ct_number
]);
return redirect('index')->with('key', 'You have done successfully');
}
SIDENOTE:
Inject Request into your method and use it instead of Input. Input was used in laravel 4 while injecting the Request class is the recommended way in laravel 5.1
I have also faced same issue with you.
My solution is to include use Flash; on top of the controller that you wanted to use the Laracasts Flash plugin.
Hope this helps.
return redirect()->route('posts.index')->with('success_msg', 'Post deleted successfully');
Here Success_msg is used to display msg on redirected page.
I'm currently building a mobile site for iPad using jquery mobile and ASP.NET MVC 4. I have a dynamically created listview that is displaying search results. I want the user to be able to click on an item in the listview and have the text from that particular list item appear in a textbox that is also in the view.
I can get this to work in Safari on my desktop machine, but it will not work on an iPad.
For the sake of simplicity and to attempt to narrow down the problem, I hard-coded a simple little listview in my View. The results were the same. Works on desktop in Safari, but not on iPad.
Here is the very simplified VIEW code that works in Safari on desktop (Please note that _Header is a separate, partial View):
#section Header
{
<script type="text/javascript">
$('#testJs li').on('click', (function () {
var results = $.trim($(this).text());
$('#testText').val(results);
}));
</script>
#{ Html.RenderPartial("_Header"); }
}
#section Content
{
<input type="text" id="testText">
<ul id="testJs" data-role="listview" data-inset="true" data-theme="c">
<li id="task400" class="tasks">Test task 400</li>
<li id="task295" class="tasks">Test task 295</li>
</ul>
}
Please note that I have tried changing 'click' to 'tap' (see below) with no success. It still doesn't work on iPad.
<script type="text/javascript">
$('#testJs li').on('tap', (function () {
var results = $.trim($(this).text());
$('#testText').val(results);
}));
</script>
I've also tried using the following with the same results. Still doesn't work on the iPad.
<script type="text/javascript">
$('#testJs').delegate('li', 'tap', function () {
var results = $.trim($(this).text());
$('#testText').val(results);
});
</script>
I do wonder if this has something to do with our use of layout pages. We have slightly different layout pages, depending on if the site is being rendered on a mobile device or not.
Mobile Layout View:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
#Scripts.Render("~/bundles/jquery", "~/bundles/jquerymobile")
#Scripts.Render("~/bundles/modernizr")
#Styles.Render("~/Content/mobileCss", "~/Content/css")
<script type="text/javascript">
$(document).ready(function () {
$.mobile.ajaxEnabled = false;
});
</script>
</head>
<body>
<div data-role="page" data-theme="b">
<div data-role="header" data-position="fixed" data-tap-toggle="false">
#if (IsSectionDefined("Header")) {
#RenderSection("Header", false) }
else { <h1>#ViewBag.Title</h1> }
</div>
<div data-role="content">
#RenderSection("Content")
</div>
</div>
</body>
</html>
Desktop Layout View:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
#Scripts.Render("~/bundles/jquery", "~/bundles/jquerymobile")
#Scripts.Render("~/bundles/modernizr")
#Styles.Render("~/Content/mobilecss", "~/Content/css")
</head>
<body>
<div data-role="page" data-theme="b">
<div data-role="header" data-position="fixed" data-tap-toggle="false">
#if (IsSectionDefined("Header")) {
#RenderSection("Header") }
else { <h1>#ViewBag.Title</h1> }
</div>
<div data-role="content">
#RenderSection("Content")
</div>
</div>
</body>
</html>
I've been stuck on this for a few days, so any help would be appreciated. Everything I try works on my desktop, but not on an iPad - which is where I actually need it to function.
Thanks!
Did you try using bind on your testJs li? I'd bind a tapHandler like below:
<script>
$(function(){
$( "#testJs li" ).bind( "tap", tHandler );
function tHandler( event ){
var results = $.trim($(this).text());
$("#testText").val(results);
}
});
</script>
or with on like this should work:
$('#testJs').on('tap', 'li', function (event) {
var results = $.trim($(this).text());
$("#testText").val(results);
console.log('this should work')
}
Also used double quotes on top example but that shouldn't make a difference I don't think. If it doesn't then make sure you .js references are correct, and use firebug in firefox to debug for any straggling errors.
I am trying to attach onBlur and onFocus handler to a SSN input field. However, I am seeing an error saying object has no method 'ON'. The code is at http://jsfiddle.net/H4Q5f/
As you can see, I commented out to figure out the details, however had no luck so far. Any help is appreciated. For convenience, here is the code:
HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Test Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
<script type="text/javascript" src="../../appjavascript/ssa/mkwr/mytest.js"></script>
</head>
<body>
<div data-role="page" id="MyTestPage">
<div data-role="header" data-position="fixed" data-logo="true" data-tap-toggle="false" data-fullscreen="false" >
<h1> Page Title </h1>
</div>
<div data-role="content">
<div class="content-primary divcontent">
<h1 class='h1title'>Using This App</h1>
<p> Here are the instructions </a>
</p>
</div>
<div class="inputdata">
<br /> <br />
<input type="text" name="accessCode" id="AccessCode" value="" placeholder="Access Code:" /> <br />
<input type="text" id="ssn1" class="ssn" value="" placeholder="SSN1:" /> <br />
<input type="text" id="ssn2" class="ssn" value="" placeholder="SSN2:" /> <br />
</div>
<input type="button" id="myalert" value="Next" />
</div>
<!-- /content -->
</body>
</html>
And here is the java script
if (typeof TEST == "undefined" || !TEST) {
var TEST = {};
}
( function() {
TEST.mkwr = {
init : function() { // this is a public function
$("[data-role='page']").on("pagebeforeshow", TEST.mkwr.hideError());
$("[data-role='page']").on("pageshow", TEST.mkwr.setHandlers());
},
// On Blur, we need to add the '-'s if they doesn't exist so the user
// view edit the entered value formatted
ssnOnBlurHandler : function(input) { // Auto format SSN on blur
if ($(input).val().length == 9) {
var _ssn = $(input).val();
var _ssnSegmentA = _ssn.substring(0, 3);
var _ssnSegmentB = _ssn.substring(3, 5);
var _ssnSegmentC = _ssn.substring(5, 9);
$(input).val(
_ssnSegmentA + "-" + _ssnSegmentB + "-" + _ssnSegmentC);
}
}, // _ssnOnBlurHandler
// On focus, we need to remove the '-'s if they exist so the user
// can edit the entered value
ssnOnFocusHandler : function(input) {
// allow backspace, tab, delete, arrows, numbers and keypad numbers ONLY
if ($(input).val().length == 11) {
var _ssn = $(input).val();
var _ssnSegmentA = _ssn.substring(0, 3);
var _ssnSegmentB = _ssn.substring(4, 6);
var _ssnSegmentC = _ssn.substring(7, 11);
$(input).val(_ssnSegmentA + _ssnSegmentB + _ssnSegmentC);
}
}, // _ssnOnFocusHandler
// Hide all errors
hideError : function() {
$(".error").hide(); // Hide all errors
},
setHandlers : function() {
alert("Set Handlers");
// $(".ssn").each( function() {
// var input = this; input.blur(TEST.mkwr.ssnOnBlurHandler(input))
// });
// $(".ssn").each( function() {
// var input = this; input.focus(TEST.mkwr.ssnOnFocusHandler(input))
// });
}
};
})(); // end the anonymous function
$("[data-role='page']").bind("pageinit", TEST.mkwr.init());
I found a couple of issues with the code on the jsfiddle. Here is an updated one that is working to fire handlers and parse code. It looks like your ssn logic might need to be fixed a little but everything is getting you to there.
http://jsfiddle.net/H4Q5f/10/
The problems I saw were partly what was mentioned before you were using .on instead of .bind given the jquery version. But also you were not setting your handlers but rather firing your handlers. You had this:
input.bind("blur",TEST.mkwr.ssnOnBlurHandler(input))
which would return the result of the function to the set method which is not what you were looking for. So I changed it to this:
input.bind("blur",TEST.mkwr.ssnOnBlurHandler)
So now you are passing the handler to the set method so that it will fire when the event takes place.
Hope this makes sense.
The .on() function was introduced in jQuery 1.7. The code you've posted above includes jQuery 1.6.4 (<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>), which doesn't have that function. You can either upgrade to the latest version of jQuery (recommended) or use the equivalent function - .bind() - for the older versions.