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"));
Related
I'm new in SailsJS so i have a question about rendering partial views.
I've came from .NET world and partial views in ASP.NET MVC are much more clever than in sails. In .NET MVC i can provide some controller as partial view path and this controller will be executed and partial view will be rendered with that controller data.
For example I want to show some account info in the corner of my website. So in .NET i can call partial view, providing controller path, this controller will query account info, provide it to partial view, and then this result will be inserted to main view.
In Sails i can call partial view, but all data (locals) for partial view will be pushed there from main view. So i have to put account information in every controller in application?
How can i solve this problem?
In other questions i've found that I can take username from req.session but it does not solve all cases. How can i show three random topics in page footer for example?
I think you are looking at the wrong place about the partial views.
This is a front-end problem .What I use for such partial views is Angular UI-router . Actually I am not sure if using angular is in the scope of the solution for you,So I'll keep this short . If you feel my method is useful ,you can comment it ,and I'll elaborate further on how to do it .
Depends on the template engine, that you use.
With ejs you can use <%- include('someview') %> or <%- include('someview', { mydata: { foo: bar} }) %>
The latter allows the include file to be called several times with diff data. E.g. <%- include('someview', { mydata: foo }) %> will copy foo (from locals) to the mydata key. This will be added to locals, so all other locals are available too.
As for providing the actual data, you can use a sails service. Just add data to res.locals.myKeyForTheInclude.
You will have to call the service each time.
But you can add it in config/http as a middleware.
middleware: {
myFoo: myService.myFunc,
order: [
...
'myFoo', // before router
'router',
...
],
All that is left is that each template needs the include.
You can not avoid that, only the template knows where the include should be.
But if you use a layout, that maybe it fits into the layout.
I need to do the following,
I have a <select> (a list of team names), when the user selects a team, I get relevant information re: the team and display it.
How do I do this in jade?
I'm trying the following, (but I'm wrong obviously, I don't see a lot of documentation out there).
Briefly, I'm doing a include test.jade on my main page, and a res.render('test', {team: team_obj});
jade:
h1 #{team}.name
h2 #{team}.homeGround
h3 #{team}.manager
h4 #{team}.aka
nodejs:
collection.findOne(query, function(err, team_obj){
res.render('test', {team: team_obj});
});
I'm getting the information correctly in team_obj.
Get the following error when I run the app,
team is not defined
Now this is happening because test.jade is getting rendered before I feed it the team_obj.
Questions:
1) Am I doing this right? is include the correct way of partially rendering jade views? if yes, how do I make sure it renders only when the user has selected an option?
2) Is there a partial views concept in jade I'm unaware of?
1) you should use #{team.name}
2) you can't change the team object once the selector is changed. the template was rendered once with the database result. - such functionality should be handled by client side JavaScript and AJAX calls. partials in templates are just a way to share common pieces of templates, and its done in Jade via include.
I don't know what you're rendering and including and when.. but id you use a template variable like #{team.name} you have to make sure that the template was rendered with the team object.
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>
Consider the following code
function populateLayout(scopeGroupId){
Liferay.Service.Portal.Layout.getLayouts(
{
groupId: scopeGroupId,
privateLayout: false
},
function(layouts){
for(var i=0;i<layouts.length;i++){
var layout = layouts[i];
alert(layout.name);
}
}
);
}
As you can see from the above Liferay's JSON service API to get all the layouts. I particularly need layout name to populate in a select box. I know that the name is stored as xml string to support different locales. I was wondering if there is javascript api to get just the name of the layout using this xml string and language id. There is a java api for doing the same as below. I need equivalent javascript API if any.
layout.getName(locale)
or
LocalizationUtil.getLocalization(String xml, String languageId)
I believe there is no such utility on Liferay's JavaScript libs.
Most of the times people need to do it in Liferay, they just parse the content in the server side and send the parsed content to the client. Frequently, the client only needs the value in the default locale; if it needs more, the developer finds a way to write it in HTML itself. See e.g. the input-localized tag where the developer writes the code to create a JS object directly in the output.
This makes sense: parsing XML is resource-costly so one would rather avoid it on client-side JavaScript. It may be even that there is a utility to do that in Liferay but I'd propose an alternative approach: just ask what you want to use in your JavaScript and write it in the HTML. For example, instead of writing the following JavaScript code
var names = Liferay.Util.Localization.nonExistentMethodToGetLocaleMap(layout.name);
for (var locale : names) {
alert(names[locale]);
}
decide in server-side which layouts to display and write the following JSP code:
Map<Locale, String> names = layout.getNameMap();
<script>
<% for (String name : names.values()) { %>
alert('<%= name %>');
<% } %>
</script>
Not much clear, I agree, but rather efficient.
I've got a layout - navigation menu. In express tutorials theres only old-school pages loading. whole old page is thrown away and a new one is downloaded with all layouts,views and partial views. And i want navigation menu to stay. So how can i do that?
If i'm maybe getting smth wrong with this web pages architecture please guide me.
As #drachenstern said, you want to render only partial HTML fragments, not whole documents including the layout. You can tell express to skip the layout using:
res.render('sometemplate', {layout: false});
If you want to look for Ajax requests as distinct from full-page browser loads, use the req.xhr flag as documented here
Thus you might even be able to do
res.render('sometemplate', {layout: !req.xhr});
You can also use res.partial() which is specifically for rendering partials.
Here is a sample of its usage, where 'browse.jade' is name of the template:
exports.browse = function(req, res){
var Contact = mongoose.model('Contact');
Contact.where({}).asc('surname', 'given_name', 'org').run(function(err, results) {
res.partial('browse', {
locals: { data: results }
});
});
};