Use fragments-like views in Symfony2 - twig

I have two tables in a database. One of them contains the users of the application, and the other one keeps some medical reports about them in a ManyToOne relationship, so every user can have a random number of medical reports in the info table.
On the left of the screen I want to display a list of the users' names, an easy thing to do. Every time I click on the name of one of them, I get to another page that shows the medical data, and I have to go back to get again the list of the users. However, I'd like to have this info in the same view, so every time I click on a name on the left I get his or her data on the right, and when I click on another user, the info of the previous user disappear and the new is shown. I mean, I want a similar behavior that the old HTML iframes had, or the new Android 4 fragments.
Is this possible in Symfony2/Twig?

Twig is just a template engine, it is parsed on the server side and raw HTML/CSS/JS is returned to the browser, you can't write interactions with the user in Twig.
Symfony is a server-side framework, which means it is parsed on the server side and raw HTML/CSS/JS is returned to the browser, you can't write interactions with users with Symfony.
You need to use a client side script lanuage, like JavaScript. You can create AJAX requests to solve your problem. AJAX requests a url and displays the content of the url on the page. As AJAX is one of the most not-crossbrowser things in JavaScript, it is recommend to use a library like MooTools or jQuery.
I recommend to create a RESTful API for the AJAX requests. Something like /users/{id} should show the user information. For that, create a controller that shows the user data and map it to the /users/{id} route:
<?php
// src/Acme/DemoBundle/Controller/UserController.php
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class UserController extends Controller
{
// ...
/**
* #Route("/users/{id}")
*/
public function showAction($id)
{
// select user by id
$user = ...;
// renders the user data
$this->render('AcmeDemoBundle:User:show.html.twig', array('user' => $user));
}
}
And now you create an AJAX request to that url to get the user data:
<ul>
<li><a class="js-show-user" data-id="1">Joren</a></li>
<li><a class="js-show-user" data-id="2">Wouter</a></li>
<!-- ... -->
</ul>
<div id="js-user-data"></div>
<!-- ... include jquery -->
<script>
jQuery(function($) {
var output = $('#js-user-data');
$('.js-show-user').click(function(e) {
jQuery.ajax({
url: '/users/' + $(this).data('id'), // request the correct url
success: function (result) {
output.html(result); // output the result
},
});
});
});
</script>

Related

Svelte store not updating subscribed value synchronously

I have a component with header which displays title. I want to update title when I change pages, so I've created a store:
export const sectionTitle = writable<string>('');
I set store value in component:
<script lang="ts">
import {sectionTitle} from "../lib/_store";
sectionTitle.set('About');
</script>
And then subscribe to it in header:
<script lang="ts">
let title;
sectionTitle.subscribe(value => {
title = value;
})
</script>
...
<h1>{title}</h1>
It does work, but seems it works asynchronously - when I switch pages, it updates after I leave page or refresh it. Like it updates after the mount and doesn't update the title property. What am I doing wrong and how to fix it? The behaviour I want is to update title prop when I load a page.
By updating the title from within the component you couple the title update to how long it takes to load the component. Depending on the router you are using, the component may be loaded asynchronously which then causes a delayed update of the title, so the problem is not Svelte itself (see this example where components are not loaded asynchronously).
I would recommend associating components/routes with titles elsewhere, e.g. in your header or a separate file, that way the title is known immediately and can be shown as soon as the route is changed.

I want to create an angular app to show live code preview like Jsbin

I'm creating the Angular app which lets user save his html code (maybe it has style and script tag to control the view) and there is a live preview next to it. User can save the code and other users can come to see the code and the preview. I also worry about the security because of script tag and I want the script to work only with the code that user provides (Not allow to control or get the data in the parent frame). So I need some suggesting of how to do it.
I have tried the preview with iFrame by giving the value through the 'srcdoc' property, but it looks like the security is bad.
You would not need to use an iframe in that situation, you can just render an HTML string inside of a div element using the innerHtml input like so:
<div [innerHTML]="htmlString"></div>
Where htmlString is a string containing the HTML code. You will have to sanitize the content of that variable with the DomSanitizer.
constructor(private domSanitizer: DomSanitizer){}
...
ngOnInit() {
this.htmlString = this.domSanitizer.bypassSecurityTrustHtml(yourHTMLString);
}

Difference between the <a> tag and get request

I have a perhaps simple question. What would be the difference between an <a> tag and a normal GET request with any element. I know the <a> tag automatically sends you to the url specified in its href attribute. So I assume that a Get request does something similar in it's success callback (as demonstrated below)
But let's say that I also want to send some information along with a normal get request when a for example <span> element is clicked on so I write:
$('span').click(() => {
$.ajax({
url: '/someurl',
type: 'GET',
data: {
title: someTitle,
email: someEmail
},
success: (data) => {
window.location = '/someurl';
}
});
});
Is there any way to achieve this with an <a> tag? Sending information to the server so it's available in req.query.title and req.query.email ?
Doing the ajax request above will run my app.get('/someurl',(req,res)=>{})twice because I am sending a GET request to send the data (title and email) and then I am making another GET request when I write window.location = '/someurl' How can I redo this so that it only sends the GET request ONCE but also allows for the sending and storing information to the req object AND ensures that the browser is now displaying /someurl.
Just create the appropriate query string in the URL you put in the href of the <a> tag and it will work just like your ajax call. Suppose someTitle has the value of "The Hobbit" and someEmail has the value of foo#whatever.com, then you can construct that URL like this:
Click Me
A number of non-letter characters have to be escaped in URLs. In the above URL, the space is replaced with %20 and the # with %40. In your particular example, you could open the network tab in the chrome debugger and see the EXACT URL that Chrome was sending for your ajax call, copy that to the clipboard and insert it into your <a> tag.
Here's a table that shows what characters have to be replaced in a query string component (the part after & or after =):
I'm just wondering then, aside from semantic reasons, is there any other advantages to using an a tag instead of anything else?
<a> tags are understood by all sorts of machines that may read your page such as screen readers for the disabled or crawlers indexing your site. In addition, they work automatically with browser keyboard support, Ctrl-click to open a new tab. Whereas a piece of Javascript may not automatically support any of that functionality. So, basically, if the <a> tag can do what you need it is widely preferred because it has so much other default functionality that can be necessary or handy for users.
Hello

Passing a variable from .ejs file back to express.js

I am working upon the project using node.js with express.js framework and view engine set to "ejs". The project's functions is to:
1. Get an input from a user.
2. Using the input send the request to the website's API.
3. Print the certain data from that API (including the ID to be used later).
4. When user clicks on the item (that is an 'a' tag) in the list consisting of the aforementioned data - use the ID of this item to send another request to the same website to get a more detailed info about the item.
I am stuck at the step 4. And the question is: How to send this id from the .ejs file to post request in node.js when the user clicks on the item?
Doing it the other way is simple: response.render("view name", {nodeJsVar: ejsVar}); But how to pass it back?
Thanks for the help!
First of all, you cannot send any data "from the .ejs file" - what you can do is to send it from the browser, that has a rendered HTML (and possibly JavaScript) and not EJS.
You can do it with some client-side JavaScript in which case you can do whatever you want.
You can do it by embedding the variable's value in a URL as a route parameter or a query parameter if you're using standard <a href="..."> links.
You can put a hidden input in a form if you're using forms and buttons.
You can put it in any part of the request if you're using AJAX.
Just to make sure you know what is what because it can be confusing - here X is a path parameter:
http://localhost/something/X
and here X is a query parameter:
http://localhost/something?x=X
try this (assuming you use jQuery):
$.ajax({
url: '/routename_to_handle_id',
type: 'POST',
data: { id: id }
}).done(function(response){
//callback to handle if it's successful
})

Data Annotations / Validation not working for partial views

I have some partial views loaded at runtime, based on user input.
$("#Categories").change(function () {
$.ajax({
url: "/Product/Create" + $("#Categories option:selected").text().replace(/\s+/, ""),
type: "Get"
}).done(function (partialViewResult) {
$("#partialDiv").html(partialViewResult);
});
});
The POCO's that are used in the view model are decorated with data annotations, but they are not triggered.
The partial views each contain a form (Html.BeginForm()).
I guess I'm doing something wrong, but not sure what. Any advice greatly appreciated.
Just Include JS files i.e Jquery Unobtrusive js file in your Partial View also then it work fine ,some times this problem comes in partial view in asp.net mvc.
Just include this js file in your Partial View also :
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
------------------OR try this in Partial View--------------------------
$.validator.unobtrusive.parse($("form"));
try this if you are appending form in html
var formid = $("#frmAddProduct");
formid.unbind();
formid.data("validator", null);
$.validator.unobtrusive.parse($("#frmAddProduct"));
OR use in partial view on document ready
$.validator.unobtrusive.parse($("form"));

Resources