Cakephp: Accessing a database table from view - javascript

I have the following code inside a view, but I'm trying to use a table instead of the array 'tags' to access the data for the autocomplete function. Can I do that because I read somewhere that the view should not interact with the model? If I can, can someone guide me how to? Please I need help! Thank you.
<script id="source" language="javascript" type="text/javascript">
$(function() {
var tags = [
"THE PAS",
"THOMPSON",
"TREHERNE",
"VIRDEN",
];
$( "#tagOrig" ).autocomplete({
source: function (request, response) {
var matches = $.map(tags, function (tags) {
if ( tags.toUpperCase().indexOf(request.term.toUpperCase()) === 0 ) {
return tags;
}
});
response(matches);
}
});
</script>

The controller should do it. Pick up the data from the model, set a variable and set it into the view. Or just use Ajax to fetch the data, while you render the view.

Related

use jquery variable in # block razor

I'm strugling with a jquery script inside a cshtml page. For short my question is how to use a var inside a # statement in a cshtml page?
below an example of what I'm trying:
<select id="DefaultText">
<option value="-1">-- select --</option>
#foreach( var d in Model.DefaultTexts )
{
<option value="#d.Id" >#d.Name</option>
}
</select>
<script type="text/javascript">
$('#DefaultText').change(function () {
var id = parseInt($('#DefaultText :selected').val());
var text = #Model.DefaultTexts.First( t => t.Id == id );
$('#CustomProductText').val(text);
});
</script>
I can't reach the var id. It's out of scope. I've also tryed it with a for loop and a if statement. But in the if statement I get the same error: out of scope.
The full story is this:
On my page I've a dropdown list. The items to select are short names for default text parts. Based on the id or name, I want to show the default text part in a textbox.
#CustomProductText is my textbox where the content should be placed (code not posted).
I've also tryed it with #: and statement but that did not work.
What am I doing wrong or maybe its not even possible what I'm trying to do.
As an alternative I've added a action to my controller to get the text form there. Below the code:
<script type="text/javascript">
$('#DefaultText').change(function () {
var id = parseInt($('#DefaultText :selected').val());
$.post("Categories/GetDefaultText", { Id: id }, function (data) {
alert(data);
});
//$('#CustomProductText').val(text);
});
</script>
controller code:
[HttpPost]
public ActionResult GetDefaultText(int id)
{
using( var context = new MyContext() )
{
var text = context.DefaultText.First( d => d.Id == id ).Text;
return this.Content( text );
}
}
This doesn't work. The action doesn't get hit in debug mode.
regards,
Daniel
The $.post that is not working for you, you should prefix the url with / sign and it will be hit as expected:
$.post("/Categories/GetDefaultText", { Id: id }, function (data) {
alert(data);
});
As for the razor solution, you can't use javascript variables in the razor code as it's not a scripting language. What razor does is simply rendering the strings (be it html or javascript or anything) into the page.
To do what you want you either need to request the server to pass the text to your page or render all the texts you have in the page and then access this rendered content in your javascript.

Tokeninput save new tag to database

I am trying to save a new tag entered in input field that was not there in database and want to save that created tag on form submit. Here is my controller which is sending the autocomplete list to the tokeninput input field:
def tags = {
def foundTags = Tag.findAllByTagnameIlike("${params.q}%")
def output = []
foundTags.each {
output.add([id: it.id, name: it.tagname]) // assumes Tag has an id field exposed
}
if(output.size()==0){
def c = Tag.createCriteria()
def maxId = c.get {
projections {
max('id')
}
}
output.add([id:(maxId+1),name:params.q])
}
render output as JSON
}
My jQuery script is:
<script type="text/javascript">
$(document).ready(function () {
$("#my-text-input").tokenInput("${createLink(controller: 'product', action: 'tags')}",{theme: "facebook",allowFreeTagging:"true"});
});
</script>
Now when I submit the form, i get params.tags as the ids of those newly entered tags in the input field.But actually these IDs do not exist and are created by output.add([id:(maxId+1),name:params.q]) just for the reason that tokeninput requires it to be there.
So how do i get the tag names in the params.tags instead of the ids? Infact i require something like this map ["id1":"tagname1","id2":"tagname2".....]. So how do i get the actual tagname instead of the id fields in the server side action which persists the form params?
Make use of the tokenValue parameter during set up.
e.g. In jQuery
<script type="text/javascript">
$(document).ready(function () {
$("#my-text-input").tokenInput("${createLink(controller: 'product', action: 'tags')}",{
theme: "facebook",
allowFreeTagging:"true",
tokenValue:"name"
});
});
</script>
This will submit an array of names instead of IDs. If you need both name's and id's, you're probably best adding a custom attribute to each token through an onAdd parameter, and then setting that to the tokenValue.

How to display value of a ViewBag in my view with a JS function?

I want to display the data from a ViewBag in my View with Javascript. Here is my code.
View
<span id='test'></span>
Javascript
function myFunction()
{
$('#test').text('#ViewBag.Test');
}
When myFunction() is called I get the text #ViewBag.Test but not his value. How can I fix this ?
You need to place your JavaScript which takes the #ViewBag.Test value in a page which is interpreted by the Razor view engine. My guess is that this is currently not the case.
If you want to keep your javascript codebase separate from the view (which is entirely reasonable) you can use a global variable:
// in the view:
var testText = '#ViewBag.Test';
// in external js
function myFunction() {
$('#test').text(window.testText);
}
Alternatively, you can use a data-* attribute:
<span id='test' data-text="#ViewBag.Test"></span>
// in external js
function myFunction() {
$('#test').text(function() {
return $(this).data('text');
});
}
What you should be ideally doing is passing the data to the view with a view model. Have a property to store that value you want to pass. For example. Let's think about a page to show the customer details and you want to get the last name in your javascript variable.
Your GET action method
public ActionResult View(int id)
{
var vm=new CustomerViewModel();
vm.LastName="Scott"; // You may read this from any where(DAL/Session etc)
return View(vm);
}
and in your view which is strongly typed to your view model.
#model CustomerViewModel
<div>
Some Html content goes here
</div>
<script type="text/javascript">
var lastName="#Model.LastName";
//Now you can use lastName variable
</script>
EDIT : (As per the question edit) To show the content on some event (ex : some button click), Store the value somewhere initially and then read it as needed and set it wherever you want.
#model CustomerViewModel
<div>
<span id="content"></span>
#Html.HiddenFor(s=>s.LastName)
<input type="button" id="btnShow" value="Show content" />
</div>
<script type="text/javascript">
$(function(){
$("btnShow").click(function(e){
$("#content").html($("#LastName").val());
});
});
</script>
Firstly make sure your ViewBag.Test does got a value, then use a div tag instead of a span and add the following code:
<script type="text/javascript">
$(document).ready(function () {
StartRead();
});
function StartRead() {
document.getElementById("test").innerHTML = '#ViewBag.Test';
}
</script>

How do I create a web link inside a javascript function and pass cell value as a parameter to servlet?

I am creating a table dynamically with JavaScript as you can see below. I want users to be able to click on the first column value and pass the value of the cell as a parameter to a J#EE servlet. Can you help me? Basically the first column should be links to a new page with a country details. How can I do that? Thank you.
Where do I put the link code?
function oneSecondFunction() {
$.get('DisplayCountries', function(responseJson) {
if (responseJson != null) {
$("#countrytable").find("tr:gt(0)").remove();
var table1 = $("#countrytable");
$.each(responseJson, function(key, value) {
var rowNew = $("<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td>" +
"<td></td><td></td></tr>");
rowNew.children().eq(0).text(value['id']);
rowNew.children().eq(1).text(value['country1']);
rowNew.children().eq(2).text(value['country2']);
rowNew.children().eq(3).text(value['country3']);
rowNew.children().eq(4).text(value['country4']);
rowNew.children().eq(5).text(value['country5']);
rowNew.children().eq(6).text(value['country6']);
rowNew.children().eq(7).text(value['country7']);
rowNew.children().eq(8).text(value['country8']);
rowNew.appendTo(table1);
});
}
});
and here is the link code. I have tried several options and it doesn't work.
id
First, assign a class to the first <td> something like <td class="linkHolder">.
Then, write a click handler to send ajax request to servlet:
$('#countrytable').on('click', '.linkHolder', function() {
var link = $(this).html();
$.post('/myservlet', {url: link}, function(response) {
//handle response here
});
return false;
});
You can access the link on the servlet side with the request parameter url

Kendo template send data

What I want is simple but I don't know if it's possible.
I have a Kendo Mobile ListView as below:
e.view.element.find("#list-serviceorders").kendoMobileListView({
dataSource: ds,
pullToRefresh: true,
template: $("#list-serviceorders-template").html()
});
And I want to send to the template some values to access on it. My view with the template is this:
<div data-role="view" data-before-show="GAPCP.viewBeforeShow" id="serviceorders" data-layout="main-item-list">
<ul id="list-serviceorders"></ul>
</div>
<script id="list-serviceorders-template" type="text/x-kendo-template" data-teste="teste">
<a href="views/entries.html?id=#: CodOs #">OS: #: CodOs #<br />
#: parameter.Divi1 #: #: CodDivi1 #/#: parameter.Divi2 #: #: CodDivi2 #</a>
</script>
Where you can read parameter.Divi1 and parameter.Divi2 are the places where I want to display those values. They're are not in the Data Source like the others values.
I don't want to create global variable 'cause I don't want to mess with my code and I can't use a function for that purpose because those values come from the database and it will execute a query for each list item iteration.
Any suggestion of how do that?
What I'm proposing is adding this information to the model in the controller. You can do it in DataSource.schema.parse or in requestEnd, even in a dataBound event if the widget accepts it.
When the data is received you iterate through the model and fills the remaining data not received from the server.
Example: Using parse
var ds = new kendo.data.DataSource({
transport: {
read: {
url : ...
}
},
schema : {
model: {
CodOs : { type: "number" },
CodDivi1: { type: "string" },
CodDivi2: { type: "string" }
},
parse: function (data) {
$.each(data, function (idx, elem) {
// Extend original elem
elem.parameter = {
Divi1: elem.CodDivi1.toUpperCase(),
Divi2: elem.CodDivi2.toLowerCase()
}
});
return data;
}
}
});
Where I compute parameter inside the parse function and set parameter.Divi1 to CodDivi1 in upper-case and parameter.Divi2 to CodDivi2 in lowercase.

Categories