I'm having a hard time figuring out what is the best way to transfer information from PHP to Jquery. I know putting PHP in Javascript is a really bad alternative (my JS and PHP files are seperated anyway), so what I usually do is print the info with PHP in the HTML with a input type hidden and retrieve the info in JQuery using the element.text() or .val() or any other method, but I feel this is kind of noobish. Is there a better way?
I recommend never using a server-side language to build JavaScript. Instead, keep your data in HTML (model), your styles in CSS (view), and your interactions in JS (controller).
When you need to pass data to JavaScript, make good use of attributes and templates.
When it comes to passing data via attributes, you can go a long way with just using native attributes.
In this example, it is quite apparent that the link will open a modal, and the [href] attribute is used to point to where the modal lives:
Open modal
<div id="modal">lorem ipsum</div>
When you can't fit data within native attributes, you should make use of [data-*] attributes.
In this example, [data-tooltip] is being used to store a rich-text tooltip.
<div data-tooltip="<p>lorem ipsum</p>">...</div>
Even more importantly, jQuery automatically grabs and casts all [data-*] attributes on a DOM node when .data() is called on the node.
<div id="example"
data-foo="bar"
data-fizz="true"
data-max="100"
data-options="{"lorem":"ipsum"}">
...
</div>
<script>
$('#example').data();
/*
{
foo: 'bar',
fizz: true,
max: 100
options: {
lorem: 'ipsum'
}
*/
</script>
The thing to watch out for is JSON encoding within HTML encoding. jQuery makes it very straight-forward to get the data out of the DOM node without needing to worry about decoding, but in PHP you need to make sure that you json_encode data before calling htmlentities:
<div data-example="<?= htmlentities(json_encode($someArray)) ?>">...</div>
In some instances you may want to make use of jQuery's .attr() method.
For large amounts of data, such as an HTML template string, you can use <script> tags with a template mime type (such as type="text/x-jquery-tmpl"):
<script id="template-example" type="text/x-jquery-tmpl">
<h1>${title}</h1>
<p>${body}</p>
</script>
Or you can use the HTML5 <template> element:
<template id="template-example">
<h1>${title}</h1>
<p>${body}</p>
</template>
You can then access the HTML contents of the element run it through whatever your favorite flavor of string templating happens to be.
You can simply echo PHP variables into Javascript variables for your jQuery to use like this:
<?php
$stringVar = "hi";
$numVar = 1.5;
?>
<script>
var stringVar = "<?php echo $stringVar; ?>";
var numVar = <?php echo $numVar; ?>;
</script>
This can be used for practically any data type as long as you convert it correctly upon echoing it (oftentimes json_encode() is enough for complex structures such as arrays and objects).
Also note that this way will only work if your jQuery code is included after these variables have been defined.
The other way is to look into using AJAX, but if these are static variables that don't need to change within the lifetime of the page then I would go with the method above.
Related
I am using Javascript to define a button behaviour on a web page. The behaviour I am after is to insert some new HTML somewhere on my page, but I would like to use the MVC extension method Html.EditorFor to define the new HTML which will be inserted.
What I would like to do is the following:
$("#myButton").click(function() {
$("#(Html.EditorFor(x => x.SomeModelProperty))").insertBefore(<somewhere>);
});
The problem I'm encountering is that the MvcHtmlString returned by the call to EditorFor renders as multi-line HTML, resulting in invalid Javascript:
$("<div>
<label for="ModelData_SomeModelProperty">SomeModelProperty</label>
</div>
<div> ....
In an ideal world, I could get EditorFor to somehow render all of the above on a single line, or use some kind of special Javascript syntax to define a multi-line string (like using single quotes in C#), but so far I'm drawing a blank.
I've tried calling ToHtmlString and hand-editing the resulting string to remove line-breaks, and I'm aware that I can escape the new lines in Javascript using a /, but the problem with doing so is that I then have to handle the escaped HTML, which looks a little like the following:
$("<div>
<label for="ModelData_SomeModelProperty">SomeModelProperty</label>
</div>
<div> .... (you get the idea)
I was just wondering whether anyone had tried anything similar and might have a more elegant approach?
One way would be to get it written into a hidden div in html instead of directly into the javascript. Then you can just read it from the dom to use in you script.
So you page would have a
<div style="display:none" id="hiddenArea">
...insert whatever you want in here
with newline or whatever...
</div>
And then in your javascript:
$("#myButton").click(function() {
var source = $("#hiddenArea").html();
$(source).insertBefore(<somewhere>);
});
You could maybe create a HTML helper so you much more control on what's returned and how it is formatted.
http://www.codeproject.com/Tips/720515/Custom-HTML-Helper-for-MVC-Application
Let's say I have a simple form setup. I can dynamically add the below element as mant times to a form via javascript.
<div class="aComplicateDiv">
<input type="text" name="myValue">
</div>
Now let's say we save these values, and then want to edit them. I can query the DB on the edit page and then from the server side, display the div with the input fields.
My issue is, when I'm adding this div, im using javascript to build the elements. However, when I display these elements on the server side, I'm using php. Seems to be repetitive, especially if I want to change the elements. I can however, from the server side, call javascript functions that pass in values to build it via javascript on the edit page, but that seems to not be the correct process. Any insight would be great on if there is a better approach or not.
The approach I mainly use in that kind situations (especially when the repeating part gets more complicated):
In PHP (extremly simplified):
function addRow($index, $data) {
echo '<div class="aComplicateDiv" id="row-'.$index.'">
<input type="text" name="myValue['.$index.']" value="'.htmlspecialchars($data).'">
</div>';
}
foreach($dataFromDb as $row) {
addRow($row['id'], $row['value']);
}
addRow('TEMPLATE', '');
In Javascript (demo)
var nextIndex = 2; // Find a way to calculate this
$('#add').click(function() {
// Append a clone of the template to a temporary div
// From that div we can get the html-content
var html = $('<div>').append(
$('#row-TEMPLATE').clone()
).html().replace(/TEMPLATE/g, nextIndex++);
$('#row-TEMPLATE').before(html);
});
In JSF, what would be the "right" and "clean" way to integrate JavaScript i.e. into a composite-compenent? I am a fan of Unobtrusive JavaScript, and separating HTML from JS from CSS. What would be a good way to have as little quirks as possible? This is what I like the best so far:
<composite:interface>
// ...
</composite:interface>
<composite:implementation>
// ...
<script> initSomething('#{cc.clientId}'); </script>
</composite:implementation>
What I don't like is, to use language A to generate language B. Basically the same goes for event handlers and stuff. My favorite would be to attach those handlers via <insert favorite DOM JavaScript library here>. Is this possible? How do you do this kind of integration?
I'd say that what you've there is the best you can get, provided that you're absolutely positive that the HTML element's nature is so unique that you absolutely need to select it by an ID, every time again.
If the HTML representation is not that unique (I can imagine that a Facelets template or include file might contain application-wide unique HTML elements like header, menu, footer, etc, but a composite component which can be reused multiple times in a single view? I can't for life imagine that), then you could also consider using an unique classname and hook initialization on it.
E.g. /resources/composites/yourComposite.xhtml
<cc:implementation>
<h:outputScript library="composites" name="yourComposite.js" target="head" />
<div id="#{cc.clientId}" class="your-composite">
...
</div>
</cc:implementation>
with in the /resources/composites/yourComposite.js (assuming that you're using jQuery)
var $yourComposites = $(".your-composite");
// ...
You can if necessary extract the autogenerated HTML element ID for each of them in a jQuery.each():
$yourComposites.each(function(index, yourComposite) {
var id = yourComposite.id;
// ...
});
We have an ASP.NET MVC3 project. We populate several parts of our site using ajax calls. Lets say we have a div in our cshtml where we want to put some search results.
<div id="SearchResult" />
We have created a list with constants for all elements that we want to refer in our Javascript files
var selectors = {
SearchResult: '#SearchResult',
...
};
When we want access the div we use selectors.SearchResult in our Javascripts.
So far, so good. But coming from a c# world where we have strong bindings, compile time warnings, etc, we think the coupling here is a little bit on the loose side. If we want to refactor our div ids we have to be very careful to find all references and update them.
Are there any good practices for keeping javascript and HTML identifiers in sync? Any templates/scripts for extracting all div ids into a javascript file?
Add a script to the view
<script type="text/javascript">
window.viewConfig = { searchResult: '#SearchResult' };
</script>
and have your JS files read this window.viewConfig.searchResult.
You could also take this further and store the id in a variable and use it.
#{
var myId = "SearchResult";
}
then use #myId so the div would be
<div id="#myId"></div>
and the script would be
<script type="text/javascript">
window.viewConfig = { searchResult: '##myid' };
</script>
I've been using JSON to handle AJAX functionality in my rails applications ever since I heard about it, because using RJS/rendering HTML "felt" wrong because it violated MVC. The first AJAX-heavy project I worked on ended up with 20-30 controller actions tied directly to specific UI-behaviors and my view code spread over controller actions, partials and rjs files. Using JSON allows you to keep view specific code in the view, and only talk to view agnostic/RESTful controller actions via AJAX to get needed data.
The one headache I've found from using pure JSON is that you have to 'render' HTML via JS, which in the case of AJAX that has to update DOM-heavy elements, can be a real pain. I end up with long string building code like
// ...ajax
success: function(records){
$(records).each(function(record){
var html = ('<div id="blah">' + record.attr +
etc +
')
})
}
where etc is 10-15 lines of dynamically constructing HTML based on record data. Besides of the annoyance, a more serious draw back to this approach is the duplication of the HTML structure (in the template and in the JS).* Is there a better practice for this approach?
(My motivation for finally reaching out is I am now tasked with updating HTML so complex it required two nested loops of Ruby code to render in the first place. Duplicating that in Javascript seems insane.)
One thing I've considered is loading static partial files directly from the file system, but this seems a bit much.
I like the idea of templating. In my experience it can really clean up that messy string manipulation!
There are many solutions, for example, check out John Resig's (creator of jQuery):
http://ejohn.org/blog/javascript-micro-templating/
I would go with creating an HTML structure that contains placeholders for the elements you'll need to update via AJAX. How much structure it applies will depend on what you're updating; if you know the number of elements you'll have ahead of time, it would be something to the effect of
<div id="article1">
<div id="article1Headline"></div>
<div id="article1Copy"></div>
<div id="article1AuthorInfo"></div>
</div>
<div id="article2">
<div id="article2Headline"></div>
<div id="article2Copy"></div>
<div id="article2AuthorInfo"></div>
</div>
You then write code that references the id of each element directly, and inserts into the .innerHTML property (or whatever syntactically more sugary way jquery has of doing same thing). IMHO, it's not really so terrible to have to assign the contents of each element, the part that you don't want to have to sprinkle through your AJAX functions is the HTML structure itself; in your app the content is volatile anyway.
However, it looks like you might have a list of an unknown number of elements, in that case it may be that you'd need to just put in a placeholder:
<div id="articleList"></div>
In that case I don't really see a way to avoid building the HTML structure in the javascript calls, but a reasonable amount of decomposition of your javascript should help that:
function addArticle( headline, copy, authorInfo, i ){
createDiv( "article" + i + "Headline", headline );
createDiv( "article" + i + "Copy", copy);
createDiv( "article" + i + "AuthorInfo", authorInfo );
}
(not working code of course, but you get the idea,)
You could use the load function in jQuery;
This loads the content of a page into a div like this:
$('#content').load("content/" + this.href.split('#')[1] + ".html", '', checkResponse);
Just make a dynamic view and you are good to go...
Just happened to find exactly what I was looking for: Jaml