I have an object in contrroller and I want to use them in view and in javascript code but I can't achived using ViewBag. my code hear :
public class MyController : Controller
{
public async Task<ActionResult> Index()
{
using (var client = new HttpClient())
{
string response = await client.GetStringAsync("http://api/controller/....");
ViewBag.VB = response;
return View();
}
}
}
and my view :
#{
ViewBag.Title = "Index";
}
#section Javacript
{
<script type="text/javascript">
function MyFunction() {
**** //I want to use DATA hear. *********
};
</script>
}
<div id="info">
</div>
How can I do this? Anyone have an idea?
You can put your data into a <script type="text/html"> node and access it from javascript via document.getElementById
<script type="text/html" id="data">#ViewBag.VB</script>
<script>
function MyFunction() {
var data = document.getElementById('data').innerHTML;
// if the data is in the json format, you can use JSON.parse:
data = JSON.parse(data);
// TODO: do something with data
}
</script>
You can also insert the data directly into javascript:
function MyFunction() {
var data = '#(ViewBag.VB)'; // or omit the single quotes if it's json data
// TODO: do something with data
}
This approach requires that the javascript code is embedded into the .cshtml file.
Another possibility is to retrieve the data directly from javascript with an ajax request. This example uses jQuery's $.ajax function:
function MyFunction() {
$.ajax({
url: "/api/controller/...",
contentType: "application/json", // tell the api-controller that we want json
dataType: "application/json", // tell the jQuery callback that it is json
success: function (data) {
// TODO: do something with data
}
});
}
Related
I'm trying to send a list of values from View to Controller. I tried a lot of solutions from the Internet but haven't succeeded.
My View HTML Table list of Data send to controller via JSON but the list is empty even when I use JSON.stringify
Heres my code
JavaScript:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script type="text/javascript">
$("body").on("click", "#btnSave", function () {
//Loop through the Table rows and build a JSON array.
var customers = new Array();
$("#tblCustomers TBODY TR").each(function () {
var row = $(this);
var customer = {};
//skill.skill_name = row.find("TD").eq(0).html();
customer.CNIC = row.find("TD").eq(1).html();
customers.push(customer);
});
console.log(customers);
console.log(JSON.stringify(customers));
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
//traditional: true,
url: "/Admin/Reconcile/Customers",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(customers),
dataType: "json",
success: function (r) {
alert(r + " record(s) inserted.");
location.reload();
}
});
});
</script>
Controller Action:
public JsonResult Customers(List<String> customers)
{
}
Firstly,you need to create a model like this:
public class Customer {
public string CNIC { get; set; }
}
Then since you pass json type data in ajax,you need to use [FromBody] in action:
public JsonResult Customers([FromBody]List<Customer> customers)
{
}
You are sending an array of objects, so for the model binder to work you should accept a List of SomeModel, where SomeModel should have a property CNIC. Check the documentation here https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api on how objects are binded.
So you are sending this:
[
{
"CNIC":"somevalue",
"CNIC":"somevalue"
}
]
And you are trying to bind it to a List of string and it will not happen. Try binding it with List of SomeModel:
public class SomeModel
{
public string CNIC { get; set; }
}
Also try this attribute [IgnoreAntiforgeryToken] above your action. If it works then, you should be sending the antiforgery token with the post request.
I can't download my XLS file via Ajax
function downloadFile(response) {
var blob = new Blob([response], {type: 'application/vnd.ms-excel'})
var url = URL.createObjectURL(blob);
location.assign(url);
}
$('#export').click(function () {
$.ajax({
type: 'POST',
url : 'factures/engagements/selected/export',
headers: {'X-CSRF-TOKEN': '{{ csrf_token() }}' },
dataType: "json",
data : {
checkboxes : checkboxValues
}
}).done(downloadFile);
});
my controller :
public function exportFacturesEngagementSelected(Request $request){
$checkboxes = $request->input('checkboxes');
$collection = collect($checkboxes);
$engagements = EngagementOrder::whereIn('id' , $collection)->get();
$date = Carbon::now('Europe/Paris')->format('d-m-Y H:i:s');
$output = Excel::create('factures_engagements' . $date. '', function($excel) use ($engagements) {
$excel->sheet('Excel', function($sheet) use ($engagements) {
$sheet->loadView('engagements.exportExcelSelected')->with("engagements", $engagements);
});
})->export('xls');
return $output;
}
I only get the output preview of the file in my console network, but nothing happens in my browser; no file is downloaded. What am I doing wrong?
UPDATE #matticustard solution :
my checkboxValues is a json for exemple the result is
{920: "920", 927: "927", 931: "931", 939: "939"}
when i console log query i get :
undefinedcheckboxes=920&checkboxes=927&checkboxes=931&checkboxes=939&
When i try to get the values to my controller i made a $request->all() and i get :
array:2 [
"undefinedcheckboxes" => "920"
"checkboxes" => "939"
]
why i get undefinedcheckboxes and why i don't get the other ids ?
Try this
if your ajax success
location.href = path/to/file/property_title.xls
change this line
->export($type);
with
->store($type, 'public/reports/', true);
These days I've used this package
(my recommendation) for converting my model's collections to XLS and export that.
As I understand, you want to download the file via AJAX. I didn't got you at all, but I just can share my experience for helping you. This working with a normal POST request, but it will not refresh your page anyway.
So this is a working example:
In Controller
public function export(Request $request)
{
$data = $request->get('data'); // get incoming data field
return \Excel::download(new ExcelService($data), "custom-file-name-with-extension.xls");
}
In Service (or you can implement this in controller too)
namespace App\Services;
use App\Models\Item;
use Maatwebsite\Excel\Concerns\FromCollection;
class ExcelService implements FromCollection
{
protected $data = null;
public function __construct($data)
{
$this->data = $data;
}
public function collection()
{
$items = Item::where('data', $data)->get(); // some query using incoming $data
return $items;
}
}
Route
Route::post('export', 'ItemController#export')->name('export');
There's really no reason to use AJAX or store the file. You can pass the checkbox data as parameters in the URL with a GET request and use an <iframe> to download the file. I guessed at the controller name, so adjust as necessary.
web.php
Change the route to GET.
Route::get('factures/engagements/selected/export', 'FactureController#exportFacturesEngagementSelected')->name('export');
JavaScript function and handler
Serialize the data as expected by your controller and make the request.
I guessed that checkboxValues was an array of values based on the actions taken in your controller. But you could serialize the form directly var query = $('form').serialize(); and adjust the controller to match the input.
function downloadFile() {
var query;
$.each(checkboxValues, function(index,value) {
query += 'checkboxes=' + value + '&';
});
$('<iframe />')
.attr('src', '/factures/engagements/selected/export?' + query)
.hide()
.appendTo('body');
}
$('#export').click(function () {
downloadFile();
});
FactureController.php
And use the download method in your controller.
// ...
->download('xls');
How can I pass a javascript variable as an variable in my php loop:
Something like this(obviously does not work):
var myJsVar = 100;
#for ($i = 0; $i<myJsVar; $i++)
... some code
#endfor
Further I tried solving this with ajax:
/**
* Get slider value
*/
$.ajax({
type: 'GET',
url: myUrl,
data: myJsVar,
success: function (option) {
console.log(myJsVar);
}
});
It returns me the success function,
Further I did this in my Controller:
public function prod(Request $request)
{
if ($request->ajax()) {
$ajax = "AJAX";
dd($ajax);
} else {
$ajaxN = "NO Ajax";
dd($ajaxN);
}
}
It did not work.
I am not sure how to proceed, hope for some help.
PHP has finished doing its work even before the page hits your browser, so passing a variable from Javascript to PHP without doing another request is simply impossible. Consider
A) Moving your loop to Javascript. Consider using some UI library like Vue.js, Angular or React.
B) Move the contents of myJsVar to PHP. If it depends on user input or browser rendering, that impossible.
C) Performing the rendering logic through an Ajax-request
$.ajax({
type: 'GET',
url: myUrl,
headers: {'X-Requested-With': 'XMLHttpRequest'},
data: {value: myJsVar},
success: function (response) {
$(someContainer).html(response);
}
});
And in your controller:
public function prod()
{
$value = Request::get('value');
return view('view-with-a-loop')->with('value', $value);
}
Be careful with the latter method XSS-wise.
I use a section in blade to add the javascript then pull that into the layout. The example below shows passing of integer/string/collection of models, eg:
// blade template
#extends('layouts.app')
#section('javascript')
<script type="text/javascript">
var myInteger = {!! $myInteger !!};
var myString = '{!! $myInteger !!}';
var myObject = {!! json_encode($models) !!};
</script>
#endsection
#section('content')
...
#endsection
// Layout (the javascript can go anywhere in the layout, ie the head or body:
<!DOCTYPE html>
<html>
<body>
#yield('content')
#yield('javascript')
</body>
</html>
One way you can do it is to render your value into a meta tag, like so:
<meta name="myJsVar" content="100">
Then use JavaScript to read that value via DOM:
var myJsVar = parseInt(document.querySelector("meta[name=myJsVar]").content);
Right now I am using a model property in the javascript as one of the values in a json object that i pass to the controller. The problem is that the javascript will be seperated in a .js file and will not be able to access #Model. So the question is; how do i access model from a seperated .js file?
You can load the external javascript as usual and the send the model value as a property to an init method like this in your view:
<script type="text/url" src="externalscript.js"/>
<script type="text/javascript">
$(function() {
var model = home.views();
model.init({
modelProperty: '#Model.Property',
});
</script>
And then your externalscript.js looks like:
(function (window) {
home = window.home || {};
home.views = function () {
pub.init = function (options) {
var property = options.modelProperty;
};
return pub;
})(window);
And you can use your property like you want to in the external script.
You could try RazorJs (unfortunatelly seems no more mantained)
Write Razor-Style C# or VB.NET inside your Javascript Files. Also
contains an http handler for serving, when needed, those files.
You could do something like this:
Views/Home
#{
ViewBag.Title = "Home Page";
}
#Html.RazorJSInclude("~/Scripts/App/TestRazorJS.js")
<button id="btnSearch" name="submit" type="button" onclick="LoadFromRazor()">Search</button>
Scripts / App / TestRazorJS.js
function LoadFromRazor() {
$.ajax({
url: '#Url.Action("Test", "Home")',
datatype: 'json',
type: 'GET',
cache: false,
success: function () { console.log('done'); },
error: function (xhr, status, error) {
console.log(status);
}
});
}
I am trying to display some data from my database that is dependent on some input from the user. I am using an ajax request to get the data, send it back to a function in my controller, and then export it back to my view. I would like to collect this data and display it without going to another view (I just hide the previous form and unhide the new form).
Here is the relevant code:
Javascript:
$('#submit_one').on('click', function(event) {
event.preventDefault();
if(! $(this).hasClass('faded')) {
var fbid = $("input[name='like']:checked").val();
//variable to be collected is fbid
request = $.ajax({
url: "http://crowdtest.dev:8888/fans/pick_favorite",
type: "post", success:function(data){},
data: {'fbid': fbid} ,beforeSend: function(data){
console.log(data);
}
});
to_welcome_two();
}
});
function to_welcome_two()
{
$('#welcome_one').addClass('hidden');
$('#welcome_two').removeClass('hidden');
}
Controller functions:
public function pick_favorite() {
$fbid=Input::get('fbid');
return Artist::specific_artist($fbid);
}
public function getWelcome() {
return View::make('fans.welcome')
->with('artists', Artist::artists_all())
->with('favorite_artist', Artist::favorite_artist())
->with('pick', FansController::pick_favorite());
}
Model function:
public static function specific_artist($fbid) {
$specific_artist = DB::table('artists')
->where('artists.fbid', '=', $fbid)
->get();
return $specific_artist;
}
The view is on the "welcome" page. My question is how do I display the model data in my view and make sure it is printing out the correct data from the fbid input?
I tried something like this:
#foreach($pick as $p)
<span class="artist_text">{{$p->stage_name}}</span>
<br>
<span class="artist_city">{{$p->city}}</span>
#endforeach
but this is not printing out anything. Any ideas?
i see lots of issues here.
Server side:
public function pick_favorite().... what does it do? it just returns some data.
in public function getWelcome() { , you wrote, FansController::pick_favorite(). supposing both are the same method, you are accessing a static method whilst the method is non static. you are getting an error for this but you are not seeing it because you didn't define fail().
and i don't see what the point of declaring a method which does nothing else then a model call which you can do directly.
e.g let's say i have a fooModel
public function index(){}
in controller, i can just write,
public function bar()
{
$model = new fooModel;
return View::make(array('param1'=>$model->index()));
}
or if i declare index() method in fooModel as static, then i can write,
public function bar()
{
return View::make(array('param1'=>fooModel::index()));
}
Client side:
now in your javascript,
$('#submit_one').on('click', function(event) {
event.preventDefault();
if(! $(this).hasClass('faded')) {
var fbid = $("input[name='like']:checked").val();
//variable to be collected is fbid
request = $.ajax({
url: "http://crowdtest.dev:8888/fans/pick_favorite",
type: "post", success:function(data){},
data: {'fbid': fbid} ,beforeSend: function(data){
console.log(data);
}
});
to_welcome_two();
}
});
function to_welcome_two()
{
$('#welcome_one').addClass('hidden');
$('#welcome_two').removeClass('hidden');
}
why it should print any data? you didn't asked the script to print anything. where is your .done or .success param in your code?
If you look at your console, you'l get lots of php errors, i am almost sure of.
an advice, you need to lear some basics. e.g. jquery ajax call.
a basic ajax call can be
var request = $.ajax({
url: "script.php",
type: "POST",
data: { id : menuId },
dataType: "html"
});
request.done(function( msg ) {
$( "#log" ).html( msg );
});
request.fail(function( jqXHR, textStatus ) {
alert( "Request failed: " + textStatus );
});
implement it in your code and then see what errors it throws.
Conclusion:
1st one will be (supposing rest of your codes are ok) the static error. if you want to call it as static, declare it as static. but a static function in controller? i don't see any purpose of it.
and then start the debug. your problem is both client and server side. deal one by one.