YII2. Using URL's in js - javascript

I have the following javascript code
$(".order-event-btn").click(function(e) {
$.ajax({
url: "URL",
type: "POST",
data: {
eventId: $(e.target).attr('data-event-id'),
},
success: function(data) {
//Some code
},
error: function(data) {
//Some code
},
});
});
I include this script using "BookAsset".
Here
url: "URL",
I need URL to the action "book-event" in the controller Book.
On the server, I can do this:
Url::to('/book/book-event')
But how do I get URL on client side?
There is an solution:
1. js file include via BookAsset.
2. in view file I register bundle:
\frontend\assets\BookAsset::register($this);
3. in view file define a bookEventURL variable. Now it is available in the js-file.
$this->registerJs('var bookEventURL = ' . Url::to('/book/book-event') . ';');
But I do not like this solution.
What will happen when I use this script in many views. I have to define a variable bookEventURL in each view?
My Question. Is it possible to bind js-variables to my BookAsset. When I register my BookAsset in the view, in page source code automatically insert next code:
<script>var bookEventURL = "http://example.com/book-event/";</script>

A proper way of doing this is to add the needed information in your button tag, e.g. :
<?= Button::widget([
'label' => 'Order',
'options' => [
'class' => 'order-event-btn',
'data' => [
'url' => Url::to(['book/book-event']),
],
],
]) ?>
And in your js code :
$(".order-event-btn").click(function(e) {
var url = $(this).data('url');
// ...
});
But if you really want to "bind js-variables" to your BookAsset, you could simply override register() :
public static function register($view)
{
parent::register($view);
$view->registerJs('var bookEventURL = ' . json_encode(Url::to(['book/book-event'])) . ';');
}

If you wanna use it in different places of your application than I guess you should place it in the layout.

Related

set processor in $http PUT request not saving proper data

Relatively new to javascript and angular. I'm using an elasticsearch instance to ingest/index different files. The webapp should have the capability to allow the user to upload multiple files, which will then be processed using the ingest processor and indexed into ES. I'm using angular-base64-upload to extract the base64 data. The following is what I've tried so far.
The html:
<div ng-switch-when="upload">
...
<input type="file" ng-model="obj.files" name="files"
base-sixty-four-input multiple>
...
<div ng-show="obj.files.length != 0">
<button class="btn btn-primary" type="submit" ng-click="ingest()">
Index All {{obj.files.length}} Files
</button> <br><br>
</div>
</div>
The javascript ingest() function code in my controller:
//Ingesting multiple files
$scope.obj = {files: []};
$scope.ingest = function () {
$scope.obj.files.forEach(function (file){
var fname = file.filename.replace(/\.[^/.]+$/, "");
var fdata = file.base64;
//Creating the pipeline
console.log('filename is: ' + fname);
$http({
url: 'http://192.168.100.30:9200/_ingest/pipeline/attachment',
method: "PUT",
data: {
"description" : "Indexing files",
"processors" : [
{
"set" : {
"field" : "filename",
"value" : fname
},
"attachment" : {
"field" : "data"
}
}
]
}
})
.then(function(allowed){
//Indexing the document
$http({
url: 'http://192.168.100.30:9200/my_index4/my_type/'+fname+'?pipeline=attachment', //unique ID for every document, ensures that there are no overlaps
method: "PUT",
data: {
"data": fdata
}
})
})
})
}
The console logging is just used for debug purposes.
The issue I'm running into is while elastic stores the file under the proper _id, which in my case is the filename, it does not store the proper field: filename. For instance, if I upload 2 files called hello.txt and world.txt, ES will store both files with hello and world as their respective _ids, but the filename field is often swapped or just generally, incorrect. I've ran the code multiple times to see if there was a pattern, and I can't really seem to find one.
The console.logs show that fname is the proper filename before the first http, after it, and after the second http, which is why I'm confused as to why the set processor is not storing it properly.
I may not have clearly explained the issue very well, as it's kind of convoluted. Let me know if anything needs extra explanation. Thanks!

How to reference Parameters passed to Partial view in a separate javascript file?

I have a Partial view in a view which take in parameters like this:
#Html.Partial("_MarkdownEditor", new { id = "editorsection" })
#Html.Partial("_MarkdownEditor", new { id = "fieldcomments" })
In the Partial view i am trying to insert a Markdown editor according to value passed in as parameters like this:
<div id="#ViewData.Eval("id")"> </div>
<script type="text/javascript">
var #ViewData.Eval("id") = new tui.Editor({
el: document.querySelector('##ViewData.Eval("id")')})
</script>
It creates a new instance of Markdown editor based on parameter passed to the partial view.
In the source code of the tui.Editor i have a Ajax call to a controller something like this..
$.ajax({
url: 'Home/Index',
type: 'POST',
dataType: 'text',
data: { capture: reader.result },
success: function (data) {
editor.importManager.eventManager.emit('command', 'AddImage', {
imageUrl: data,
altText: 'image'
});
},
Here the problem is with this line..
editor.importManager.eventManager.emit('command', 'AddImage)
Here in the place of editor i need to reference the parameters passed to Partial view..it should be like this:
editorsection.importManager.eventManager.emit('command', 'AddImage)
fieldcomments.importManager.eventManager.emit('command', 'AddImage)
It should be done dynamically i have tried something like..
{#ViewData.Eval("id")}.importManager.eventManager.emit('command', 'AddImage)
But this doesn't work like this? How can i reference the Parameters passed to Partial view in a separate javascript file??

How to get a value of a function from a javascript file to an ASP.NET MVC view?

i am trying to separate my view from java script,in my view im calling a function in js file to create a chart,
Here is my js file and the function:
function pieChartForInterventions(chartID,pieChartData) {
chartID.kendoChart({
dataSource: {
data: pieChartData
},
series: [{
type: "pie",
field: "list",
categoryField: "mm",
padding: 0,
labels: {
visible: true,
}
}],
seriesClick:onDb,
tooltip: {
visible: true,
template: "${ category }"
}
,
legend: {
position: "bottom"
}
});
}
function onDb(e) {
var _clicked = e.category;
}
here is my view:
pieChartForInterventions($("#pieChart"), result);
now the problem is,as you see in my function i have a onDb() function whick invokes when i click on my chart to get the value of what i clicked,i need this value to send it back with a Ajax call via my view,how should i have this value in my view?
Please elaborate a bit more, where exactly in your view do you require this value? OR what do you want to do with this value after receiving it in the view?
If you have something available in javascript, it means you already have it in your “View”, since the only place your javascript logic is executing is in your view.
From your onDb(e) function, you can:
1) Return the value and use it anywhere you need within the view via javascript logic.
In your sepearated js file you may have a function like:
function onDb(e) {
var _clicked = e.category;
return _clicked;
}
Somewhere in your view (.cshtml) you may do something like:
<script type="text/javascript">
// Get 'e' from wherever you need
var requiredValue = onDb(e);
// Any Javascript / JQuery / Ajax logic ...
</script>
2) If the returned value is required at the server side, you can send an AJAX request etc. See the following on how to send an AJAX request (MVC jquery ajax call with input parameter)
==== UPDATE AFTER COMMENT ====
You can access the onDb function the same way as I mentioned in the second code snippet. However, in that case getting the input parameter “e” would require some scripting.
Alternatively, what’s even easier in this scenario is that you can move the “Ajax Call” inside onDb(e) function. Update the onDb(e) function as follows …
function onDb(e) {
var _clicked = e.category;
$.ajax({
type: "POST",
url: '#Url.Action("ControllerName", "ActionName")',
contentType: "application/json; charset=utf-8",
data: { valueToSend: _clicked },
dataType: "json"
});
}
And on your server side you would have some action like:
public class ControllerName : Controller
{
[HttpPost]
public ActionResult ActionName(string valueToSend)
{
//The value you needed is stored in the input paramater 'valueToSend'
//... process however you want and return any ActionResult ...
return Json("success", JsonRequestBehavior.AllowGet);
}
}

Is it possible to update js file using php command?

I have script.js file. and it has following array
script.js
'COntent': function() {
var contentFacts = {
blocks: {
'block1': {
name: 'yleow',
title: 'H2',
type: 'content'
}
}
};
}
},
I tried like this in my php , but it did not work :(
$lines = file($path.'/script.js');
$lines[64] = "'block2': {name: 'yleow',title: 'H2',type: 'content'}"
file_put_contents($path.'/script.js', implode($lines));
I want to add another element call block2 for this array. How can i update my script.js file function using php?
Is it possible using file_put_contents? please advice
JavaScript is a very poor substitute for a database or any other structured data format. In this case even more because you are trying to inject content into source code.
What you probably want is some form of structured data outside of your code for example a JSON file or an SQLite database.
PHP does support parsing from and serializing to JSON:
json_decode
json_encode
Possible solution
Put the contentFacts into a seperate JSON file
{
"blocks": {
"block1": {
name: 'yleow',
title: 'H2',
type: 'content'
}
}
}
Manipulate JSON with PHP
$json = file($path.'/blocks.json');
$blocks = json_decode($json, true);
$blocks['block2'] = array(
'name' => 'blue',
'title' => 'h3',
'type' => 'content'
);
Write back to JSON file
$adapted_json = json_encode($blocks);
file_put_contents($path.'/blocks.json');
Now you need to get this into your JavaScript part, I assume on the client. You can do this by requesting it from the server:
const contentPromise = fetch('/path/to/blocks.json');
contentPromise.then((blocks) => {
// Do something with those blocks. (render them to the page?)
});

Calling a controller function in javascript that will store an entry in a database using ajax (Laravel 4)

I am trying to store an entry in a database after a click using an ajax call to a route that calls a controller function in javascript (in Laravel 4).
I have a resource "artists", that is controlled by an "ArtistsController". The view where I am making the call is called "show.blade.php" in an "artists" directory (i.e. the page shows different artists: artists/1, artists/2, etc...).
I also have a table called "fanartists", where I want to store this data. Basically, when a user clicks a button on a specific artist's page, I want the relationship to be stored in this table.
Here is the relevant code:
show.blade.php:
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '*****************',
status : true,
cookie : true,
oauth : true
//xfbml : true
});
$( '.opener' ).click(function() {
FB.ui({
method: 'feed',
link: 'http://crowdtest.dev:8888/artists/',
name: 'Hello',
caption: 'Hello',
description: 'Hello!'
});
request = $.ajax({
url: "/artists/fbclick",
type: "post",
data: serialised data
});
});
};
</script>
<a class="add-list-button-no-margin opener" style="color: white; font:14px / 14px 'DINMedium','Helvetica Neue',Helvetica,Arial,sans-serif;">Play my city</a>
ArtistsController:
public function fbclick($id) {
$artist = Artist::find($id);
$fanartist = new Fanartist;
$fanartist->artist_id = $artist->id; //the id of the current artist page (i.e. artists/1, id=1)
$fanartist->fan_id = Auth::user()->id;
$fanartist->save();
}
routes:
Route::get('/artists/fbclick', array('uses' => 'ArtistsController#fbclick'));
When I include the ajax request, the FB feed does not pop up. When I remove it, it does. Also, it is not storing the data in the database like I want it to.
Do you see anything wrong here? Your help is much appreciated. Thank you.
I see some slight mistakes in your script.
In your ajax request you are using post as the method, but you have defined your route as get so either change your route to post or change ajax method to get. I will go with post route so your new route is Route::post('/artists/fbclick', array('uses' => 'ArtistsController#fbclick')');
And ajax data field should be in json format, so now you ajax request will look some what like this
$.ajax({
url: "/artists/fbclick",
type: "post",
data: {field_name :'data'}
});
Finally coming to you controller function, with silght changes
public function fbclick() {
// $artist = Artist::find($id);
$id=Input::get('field_name'); //field_name is the field name from your Json data
$fanartist = new Fanartist;
$fanartist->artist_id = $id; //the id of the current artist page (i.e. artists/1, id=1)
$fanartist->fan_id = Auth::user()->id;
$fanartist->save();
}
Everything should work now

Categories

Resources