Get model values in separate Javascript file - javascript

I'm using ASP.NET MVC 2 and stuck with the situation when needed to store all javascripts in separate javascript files.
But in some pages Javascript's contains information from server-side, so I need a way to do something like this.
I want to make separate JS files and include them in Site.Master. But still I want to make workable code blocks like this
loadNews("<%= Model.A%>", "<%= Model.B%>");
Is there any way to do some trick?

I'm a newbie on MVC and also facing that situation. I'm dealing with it by calling the javascript functions via a script block on the view.
Something like this:
--On MyFile.js
function loadNews(a, b) {
//Do fun stuff
}
--On Index.cshtml
<script type="text/javascript">
loadNews("<%= Model.A%>", "<%= Model.B%>");
</script>
Another option could be declare the variables on the view's script block and referencing those variables on the javascript, since their scope would be global. Would be an ugly thing and a bit harder to mantain, but also could do the job. Like this:
--On MyFile.js
function loadNews() {
doSomethingWithA(a);
doSomethingElseWithB(b);
}
--On Index.cshtml
<script type="text/javascript">
var a = "<%= Model.A%>";
var b = "<%= Model.B%>";
</script>

We had the same issue previous and found a nice solution using jQuery.
Firstly, we extend jQuery with our own namespace (we placed the following in a separate JS file and included it on the masterpage):
$.extend({
myProject: {
dataitem: {},
dataitems: function (a) {
$.extend($.myProject.dataitem, a);
}
}
});
Now, whenever we have a value that we want to pass to our JS file from the ASP view, we simply add the following to the view:
<script type="text/javascript">
$.myProject.dataitems({
foo: Model.Bar,
bar: Model.Foo
});
</script>
Now, for your separate JS file (which would be included below the aforementioned <script></script> block) accessing the value is simple:
$('#foo').click(function () {
alert($.myProject.dataitem.foo);
});

Can you put the data in hidden fields, then access them with Javascript?
<%= Html.HiddenFor(x => x.A) %>
loadNews($('#A').val());
EDIT: Sorry, MVC2

Related

Using Ruby Variables in JavaScript

I'm new to Ruby so I had a question in regards to using some variables throughout my codebase. I have a variable declared in my Ruby file as follows:
#pages = 350
Now, I know that in HAML, I can simply do:
-if #pages = 350, and in HAML with inline javascript, I can do something like:
:javascript
console.log("#{#pages}");
However, I am linking an external JavaScript file in my HAML document, and I was wondering if it would be possible to use my Ruby variables in my external JS document? I need some variables in order to build what I am trying to build. Thanks!
Update as per one of the answers:
In my HAML file, I have the following:
:javascript
printPages(3);
In my external JS file, I have:
$(function() {
window.printPages = function(pages) {
console.log(pages);
}
});
I you are loading static javascript files I really would not recommend trying to insert variables into that code.
Instead, think about how you would provide that to your javascript code.
You could send it to that code as an argument.
<script type="text/javascript" src="./my-external-script.js"></script>
:javascript
runMyExternalFunction(#{#pages})
Or you could add the variable as a data attribute on your page, and your javascript could look for that when it loads.
Haml:
%body data-pages=#pages
JS:
console.log(document.body.dataset.pages) // value of #pages
Update about your javascript:
Using jquery's on page ready event $() for declaring the function is a bad idea. That means that it waits for everything on the page to be compeletely loaded, and then declares the function your page needs.
What you should be doing is setting up all the function that will be needed right away, and then calling those functions when the page is loaded.
They way you have it, the page loads, printPages() is executed (which doesn't exist yet), and then after all that printPages is created and put into the global scope.
So remove the $() from your external script and add it to your HAML instead.
In fact, if your aren't doing anything super fancy with transpiling or bundling, then you can simply declare the function in your external JS file, and it will be available globally. This doesn't work with your code because they way you've declared the function, it would only be available to code within that $() callback.
// js file
function printPages(pages) {
console.log(pages);
}
HAML:
$(() => {
printPages({#pages})
})

How to access objects in an external js file from another external js file

Hello fellow programmers,
I am wondering today how to access objects from another external js file. I'm using this as a way to organize my code throughout multiple js files. Here's an example of what I'm trying to say.
Imagine this as the code from an external js file:
$(function () {
function Person() {
this.name = "Bob";
}
})
And I want to access that object in another js file:
$(function () {
var person = new Person;
alert(person.name);
})
Is there a way to do something like that? How would I need to position the html?
My first wonder is why you have your JS wrapped in a function like so. You can see here I've accessed "hello" from another script loaded after it's set - as it's set in the global space.
https://jsfiddle.net/sj7bp97c/
<script src="https://pastebin.mozilla.org/?dl=8907696">
</script>
<script src="https://pastebin.mozilla.org/?dl=8907697">
</script>
One script sets the value, the other prints it to console. Unless it's required for your Javascript to be surrounded by functions, I'm not sure why you're doing so.
Reveal the function to the global scope:
$(function () {
function Person() {
this.name = "Bob";
}
return {
Person: Person
}
})()
When revealed to the global scope, you access it from within another JavaScript file as soon as the script has initiated. So you'll want to include it after you included this one.
You just need to mention both of your js script files in head section of html.
Javascript will take care rest of the things.
<head>
<script src="First.js"></script>
<script src="Second.js"></script>
</head>

What is the standard workaround for dynamic js files

Is there a standard workaround for something like this in ASP.NET:
//myinclude.js
$(document).ready(function() {
for(recs=0; recs < {{server-side-value}}; recs++) {
// process records
}
});
Note this is a js file. I know about WinForms ability to insert dynamic quoted scripts into the page. But how about a page's js file that is dependent on server-side values? I know you can use something like:
//myview.cshtml
var instance = new MyObject(<%= ServerSideValue =%>);
and include it on the page to pass it to the js file, but I'm wondering about the architecture of keeping js separate from html code so that an html/css designer can work with the template free of javascript; keeping everything separate. I primarily use MVC now.
What are some of the patterns to deal with this? Is the only solution dynamically inserting js into the actual page or having partial views included separately into the page.? Or is there a way to sprinkle server-side values in separated js? In short, no dynamic js files?
I'm not trying to fix an exact project at this time, I have just been curious about this on past projects.
Thanks...
There are multiple ways to achieve this. One of the ways would be populating your data into a Javascript objects on the HTML page directly.
//myview.cshtml
<script>
var pageData = {
name : '#variable1',
value1: #value1
};
</script>
And, in the javascript file:
//pageUI.js
if (pageData) {
$('#page_tile').html(pageData.name);
}
I am sure you can optimize a whole lot (for example, having a single communication between the server side data and the client side code). At the end of the day, you want to make sure that your javascript code can be resusable.
for example one can do this:
A. have the main .js code read any context-specific parameters from the current window like this (page.js):
!function(window){
var configData = window.MyAppNameConfigData;
// rest app code here..
}(window);
B. the server side script can inject these context-specific data in the page's html like this:
<script>
window.MyAppNameConfigData = {
param1: //..
param2: //..
// etc..
};
</script>
Note if needed make sure that the page.js is enqueued/loaded after the data have been injected/inserted (using a script dependency chain for example)
If it's not "inline" (on the View/Page itself), you could do a Partial View/Page:
Trivial example: _PartialJs.cshtml
$(document).ready(function() {
var foo = "#DateTime.Now.Year";
});
Then in your view:
<script>
#Html.Partial("_PartialJs")
</script>
Renders:
<script>
$(document).ready(function() {
var foo = "2015";
});
</script>
Hth...

Grails 2.0: Use Service in javascript function in GSP

I am just wondering how I can call a method of a service from within a function within a GSP. I tried the following but it does not seem to work:
<%# page import="com.company.MyService" %>
<%
def myService =grailsApplication.classLoader.loadClass('com.company.MyService').newInstance()
%>
<html>
<head>
[...]
<script language="javascript">
function myFunction() {
if (${myservice.isSomethingAvailable()}) {
[...]
}
}
</script>
I am pretty new to javascript and Grails. Not sure how to achieve that or if it's even possible. Any help appreciated.
Thanks a lot
Jonas
loadClass().newInstance() creates new instance of object, not spring bean (i mean it's not tied to grails infrastructure), i'm sure it's not what you want
You can pass service from your controller, like render(model: [myService: myService]) (you have to declare it at controller lever)
It's much more correct way is to pass result of this call, not service itself. I mean: render(model: [isSomethingAvailable: myService.isSomethingAvailable]) and test it as if ($(isSomethingAvailable)) {
Notice that gsp is processed in server-side, not client-size. So it doesn't matter where you use your variable - on javascript code, or html code. And also, you can use gsp if tag: <g:if test="${isSomethingAvailable}"> instead of preparing javascript to check value on client-side (because you already know the result)

How to organize javascript file into smaller pieces?

I currently have one large external javascript file that is used on the page. I currently wrap the code in a self-invoking function because I have other sections that are loaded using ajax tabs, so I want to avoid naming clashes with those other external js files.
The code in the file is organized like below. I would like to split some of the code inside the plannerTab namespace into smaller files, yet still have it be part of that namespace.
How could I do this? Or, do you guys recommend a different approach? Thanks!
// Document Ready
$(function ()
{
// initializes table
plannerTab.plannerTable.init();
});
var plannerTab = (function ()
{
// All the code for the page is in here. I would like to extract sections
// from in here and put them into their own external files while still keeping
// the namespacing
}();
Update
How could I separate parts from within the plannerTab variable into smaller external js files, and still maintain that they are part of the plannerTab namespace? A small example below.
// Scope: plannerTab.config - Would like to store configuartion into a separate file
var config = {
selectors: {
tableId: '#plannerTable',
addTaskId: '#AddTask',
editTaskSelector: '#plannerTable .edit',
dateFilterSelector: '#plannerTable_TimeFilter li',
deleteTaskClass: '.delete',
searchFilter: '#plannerTable_filter',
selectedDateFilter: 'selected-dateFilter',
taskCellSelector: '#plannerTable .task-col',
taskClass: '.taskId'
},
urls: {
addTaskFormURL: '/Planner/Planner/LoadAddTaskForm',
editTaskFormURL: '/Planner/Planner/LoadEditTaskForm',
deleteTaskURL: '/Planner/Planner/DeleteTask',
getTasksByDateRangeURL: '/Planner/Planner/GetTasksByDateRange',
viewTaskURL: '/Planner/Planner/ViewTask'
}
};
Look at this example (from google)
<script type="text/javascript">
function importScript(url){
var tag = document.createElement("script");
tag.type="text/javascript";
tag.src = url;
document.body.appendChild(tag);
}
window.onload = function(){
// imports go here
importScript("foo.js"); // example
};
</script>
I'm assuming that plannerTab becomes an object return result of the self executing function. If you need to add properties or methods to that object dynamically, you can take a look at jQuery.extend() http://api.jquery.com/jQuery.extend/
You would need to modify the external JS to use the jQuery extend method to add onto existing properties and methods of plannerTab. As long as you keep plannerTab a global variable, you will continue adding to it as you import more external js files.
If you are using the module pattern to maintain private variables in plannerTab, be sure to test how those values behave once you use jQuery.extend().

Categories

Resources