Dynamically update Javascript variables using Jinja? - javascript

I have a web form created that requires template creation by the user. Calling all previous entries that are templates isn't an issue, but passing the information to the form when called seems to be tricky. Basically I want the user to be able to select a template from the dropdown (See the screenshots and stuff below), then based on their selection, update the variables in the script to autofill form data. Right now, it only selects the most recent entry. Is this possible just using python/flask/javascript or am I missing something? Any help would be appreciated! Thanks!
Template Dropdown
<label for="template_select">Select Template</label>
<select class="form-control" name="template_select" id='template_select' onchange='changeTemplate()'>
<option value=''></option>
{% for template_info in template_search %}
<option value='{{template_info.client_name}}'>{{template_info.client_name}}</option>
{% endfor %}
</select>
Javascript to change values
{% for template_info in template_search %}
<script>
function changeTemplate(){
var template = document.getElementById('template_select').value;
document.getElementById('client_name').value='{{template_info.client_name}}';
document.getElementById('client_name').innerHTML='{{template_info.client_name}}';
}
</script>
{% endfor %}
Python Passing in the Query
template_search = newmatter_model.NewClientMatter.query.filter_by(
creator=verifier, is_template='on').all()

Your mistake is to create Javascript code in a loop. You don't need to do this.
What you want to do is think of the data sent to the browser as independent. Make it work first without Flask and Jinja2. Create a static page that works and does what you want.
The following code would work with static data:
function changeTemplate(){
var template = document.getElementById('template_select').value;
document.getElementById('client_name').innerHTML = template;
}
<label for="template_select">Select Template</label>
<select class="form-control" name="template_select" id="template_select" onchange="changeTemplate()">
<option value=""></option>
<option value="Client 1">Client 1</option>
<option value="Client 2">Client 2</option>
<option value="Client 3">Client 3</option>
</select>
<div id="client_name"><i>No client set</i></div>
That's HTML for a select box, a separate <div> element, and Javascript code to copy the selected option value into the <div>. Note that the Javascript code doesn't know anything about what data is involved; no client names are stored in the code. All that the small function does is to copy the value from the currently selected option, to somewhere else.
Once that works on its own you can start thinking about how you are going to insert the values from your application. In the above code, all that needs replacing is the dropdown options, because the Javascript code can then access everything it needs from the <select> element value.
So the Javascript code doesn't need to be generated at all, you only generate the <option> elements, as you already did in your question.
You rarely need to generate dynamic Javascript code, and it would be much better for your app if you don't. Static Javascript code can be served by a CDN and cached in the browser, removing the need for your app to keep serving that again and again for all clients. Try to minimise that whenever you can.
Instead, generate just the data that the code needs to operate on.
You can put that information in HTML tags. In the above example, your data is put in the repeated <option> tags. Or
you could add data attributes to your HTML, which are accessible both to Javascript code and to CSS. Or
use AJAX to load data asynchronously; e.g. when you pick an option in the <select> box, use Javascript and AJAX to call a separate endpoint on your Flask server that serves more data as JSON or ready-made HTML, then have the Javascript code update your webpage based on that. Or
generate JSON data and put it directly into your HTML page. Just a <script>some_variable_name = {{datastructure|tojson|safe}};<script> section is enough; then access that some_variable_name from your static Javascript code to do interesting things on the page. JSON is a (almost entirely a) subset of Javascript, and the way the tojson filter works is guaranteed to produce a Javascript-compatible data structure for you. The browser will load it just like any other embedded Javascript code.

Related

Circumventing PHP's max_var_lim on POST method

I am a newbie in the PHP language and have been struggling with this particular problem.
I am trying to workaround the max_var_lim for retrieving data via POST in PHP. I am currently collecting data as follows, using a selectbox to retrieve data and putting them in an array to store in POST. Below is the code I have in my blade.php file:
<form action={{route('account.confirm')}} method="POST">
<select class="select-cats" name = "categories[]" id="optcatlist" multiple="multiple">
#foreach ($categories as $cat)
<option value="{{$cat->id}}" #if($user->company->categories->contains($cat->id)) selected="selected" #endif>
{{$cat->name}}
</option>
#endforeach
</select>
</form>
The problem is, there are a ton of options (>1000) so in the case where all are selected, I am only able to retrieve the first 1000. I am unable to change the php.ini file, so that solution is a no-go.
My question is, how do I access $_POST["categories"] on this page and implode this into a single string so I can pass it on using POST without exceeding the max_var_limit?
A detailed answer would be much appreciated as I just started using PHP and don't know left to right.
Thanks!

Use View model in Javascript

Scenario:
A partial view has a model, I need to use the value from the model in the javascript which is in seperate .js file.
Currently, I'm using javascript inline so that the value in the model can be used, but what if, the javascript is moved to a seperate file. In this case how do I get those values.
Code
#model IEnumerable<BookSpec.DomainEntities.ContactModel.ContactDataModel>
<label for="SpecFinder">Contact</label>
<select id="SpecFinder" name="state">
#foreach (var name in Model)
{
<option value="#name.GroupID">#name.GroupName</option>
}
</select>
<script type="text/javascript">
$(document).ready(function () {
$("#SpecFinder").change(function(){
getData(this.value,'#Model.ProductID');
});
})
</script>
This is my current example code looks like, and I want to completely move the inline javascript to a seperate file. How can I do it, I also need the values from the model.
Declare global javascript variable model on view as below. Then you can use it anywhere.
<script type="text/javascript">
var model = #Html.Raw(Json.Encode(Model));
</script>
I will recommend to use above solution. But if you still want to not include any script in partial view then you can render the model inside any hidden div. And access its text and convert it to object using JSON.parse as below. Code like below is not a good practice and like patch work.
HTML
<div id="model" style="display:none;">
#Html.Raw(Json.Encode(Model))
</div>
Script
var model = JSON.parse($("#model").text());
I think #Karan response is a good option. But if you want no inline Javascript, you could assign your model to a hidden HTML input and then retrive the value in whatever other external JS file you want.
With something like Html.Hidden, for example:
#Html.Hidden("myModel", new Microsoft.Web.Mvc.MvcSerializer().Serialize(model, SerializationMode.Signed));
You can choose another serialization mode in the SerializationMode enum.
(Code not tried, but should be close)

Getting the selected string in the dropdown list in Angular

To begin with, I am an absolute beginner in front-end development, thus please excuse me if the question is too elementary.
The project I am working on, a drop-down list has been defined as:
<div ng-controller="FacetController">
<div class="spnlocationdrop-container" ng-hide="isservicelocal">
<select class="spnlocationdrop" ng-model="$parent.locationsearch" ng-options="location for location in locations | sortArray ">
<option value="">All Cities</option>
</select>
</div>
</div>
The list contains cities, out-of which the user has to select one. The value has to be stored, and sent to the backend via an AJAX call.
How do I get the selected value? Until now, I've been doing that using the document.getElementByID().value() function, but since the above list contains no ID, how do I get the value?
ng-model will have the value of the option selected.
Here's a simple working example: Plunker
In my example, data.singleSelect has the value you need so I'm able to output that to the view using {{ data.singleSelect }} though if I wanted to access it in my controller I would do var input = $scope.data.singleSelect and then pass that input variable to the backend via an AJAX call.

select2 set preloaded tags from html option

I have the following html, the <option> tags are generated by me (by php, more precisely symfony3)
<select
name="simple_event[tagsList][]"
id="js-tags-list"
class="form-control"
multiple
data-tags="true"
data-placeholder="add-category-separated-by-semicolon"
>
<option selected>html</option>
<option selected>select2</option>
<option selected>jquery</option>
</select>
I use select2 with the followig snippets
$("#js-tags-list").select2({tokenSeparators: [";"]});
I thought it would have put the 3 tags as preloaded data, but it actually only put them as preloaded "suggestions" (which I thought would have been the case if I had not put the selected attribute)
Is there a way to do this (i.e preload data) without needing to generate my javascript with my php (which seems really dirty to me) ?
If you load the values from a database, Symfony already provides something that preloads data. http://symfony.com/doc/current/reference/forms/types/entity.html

Adding values to a select box using ajax and organising javascript files

I want to create a page where everything is loaded via ajax calls, so the URL always stays the same. At first the user will be presented with one box with some choices. According to the choice he makes another one will appear and again according to the choice he makes on the second a third will appear. I have successfully created this logic using ajax bit like the following. I am sorry if the code is a bit meshed up, but I am typing the question from a different machine than my code is located, so please be gentle. If you have any problem I will try to provide as much info as I can. So the html
<!DOCTYPE html>
<html>
<head etc....>
<body>
<div class="main-nav">
</div><!--some navigation things here not important-->
<div class=controls>
<div class="select-control1">
<select>
<option selected="selected" value="">Choose one of the following</option>
<!-- adding the django code for this select-->
{% for option in options %}
<option value="{{option.id}}">{{option.name}}</option>
{%endfor%}
</select>
</div>
<div class="select-control2" style="display:none;">
<select>
<option selected="selected" value="">Choose one of the following</option>
</select>
</div>
</div>
</body>
<html>
Also the option1 and 2 in each control1 are prepopulated by a django template for tag (it is a django project).
the ajax calls are triggered on change of each control and the view that is executed from behind sends an array of json_objects
$(".select-control1 select").change(function (){
option = $(this).prop("value");
//Skipping the case where option value is "" for now
$.ajax({
url:'/url/to/view/',
dataType:'json',
type:'GET',
success:onSuccess1
});
});
function onSuccess1(data, status, jqXHR){
$.each(data, function(index, value){
html = "<option value="+value['id']+">"+value['option']+"</option>";
$(".select-control2 select").append(html);
});
$(".select-control2").show();
}
As i said not intrested in error checking or what happens if user checks a different option in select-control1. I do remove them and place the newly gotten ones from the ajax call, just didn't right that right now. My problem are 2 + 1. First of all when the second control is populated with options after the ajax call the "Choose one of the following" option dissappears. Is that the natural behaviour of append?Is there another way?
Second even though i have the selected attribute in the first control in the "Choose one...." option when the page is loaded i don't it won't appear as selected but it will give one of the options loaded from django e.g. option1
Third and final: I am fairly new to ajax and javascript in general, and this kind of programming. I am familiar with procedural languages and can organize them as I want. But Javascript is giving me a hard time. Right now I have a veeery large js file, that will include all ajax and jquery calls of all elements on the page. Is there a way to "modulize" it in a way, to seperate it in different files somehow?Any good links pages books that could give me a guidness?
Thanks in advance!!
This is because of "<option value="+value['id']+>". You missed "
It should be
"<option value="+value['id']+">"+
Or simply try
$(".select-control2").append(new Option(value['option'], value['id']));
If your browser is IE8, the above code won't work. In such cases you have to use something like this,
var opt = new Option(value['option'], value['id']));
$(opt).html(value['option']);
$(".select-control2").append(opt);

Categories

Resources