Is it possible to chain directive scopes (e.g. obj.prop)? - javascript

I have the following directive:
template: '<form novalidate class="form-inline" ng-submit="submit($event, building)">' +
'<div class="form-group">' +
'<label class="form-control-static">{{label}}</label>' +
'</div>' +
'<div class="form-group">' +
'<input name="input" class="form-control" type="text" ng-model="model" />' +
'</div>' +
'<input class="btn btn-default" type="submit" value="Submit" />' +
'</form>',
scope: {
label: "#",
building: "=",
model: "=",
//type: "=",
},
Right now I have to write something like this in the HTML:
<building-field label="name" building="building" model="building.name"></building-field>
I would like to simply it by just needing to add the building and the label (and then put them together inside the directive ng-model="building.name):
<building-field label="name" building="building"></building-field>
The problem is, I don't know how to pass two directive scopes and like them as obj.prop. How to do this?

You don't have anything special to do, obj.prop is supported. In your template:
<input name="input" class="form-control" type="text" ng-model="building[label]" />
As a side note, you are binding label with a interpolation (type #). This means that as is, you will always have the string "name" in scope.label. If you want to actually pass the value of name, you need to use double curly brackets:
<building-field label="{{name}}" building="building"></building-field>

Related

javascript continue refreshing page after api load

I'm trying to send a request and get answer from my own synonyms api. The api works very well. And the javascript is getting the answer, but it keeps refreshing the page and in the end there's no output in my html.
This is my html script:
<form method="POST">
<input type="text" class="question" />
<button class="gen-syn">Generate synonyms</button>
<input type="submit" value="Save"/>
</form>
And this is my javascript:
$(document).on('click','.gen-syn',function(){
var questionVal = $(".question").val();
if (questionVal == ''){
$(".question").focus();
}
else {
$.ajax({
type :'POST',
url : "http://192.168.1.9:5000/synonyme_word/"+questionVal,
success : function(response){
var divSynonymes = $(document.createElement('div'));
$(".question").after(divSynonymes);
for (var a in response){
$(divSynonymes).append('<h1 class="titre-textareal-question-icona-go " value=>'+a+'</h1>'+
'<div class="form-group row" >'+
'<div class="col-sm-12 listeSyn">'+
'</div>'+
'</div>'
);
for (syn in response[a]){
var synonyme = response[a][syn]
$(".listeSyn").append(
'<input type="checkbox" name="checkboxes[249]" id="frm-test-elm-110-100" autocomplete="off" />'+
'<div class="btn-group">'+
'<label for="frm-test-elm-110-100" class="btn btn-primary">'+
'<span class="fa fa-check-square-o fa-lg"></span>'+
'<span class="fa fa-square-o fa-lg"></span>'+
'<span class="content">'+synonyme+'</span>'+
'</label>'+
'</div>');
}
}
},
});
return False;
}
});
I didn't make any reload, but the navigator keeps reloading after calling the api (when I click on Generate synonyms button)
Get rid of the <form> altogether. Its behaviour messes with your code. Just use a <div>.
This should fix your issue.
<input type="text" class="question" />
<button class="gen-syn">Generate synonyms</button>
<input type="submit" value="Save"/>
you need only one button to make a API call and then your JS code is creating dynamic div and other elements to show the synonyms.
Hope this helps.

Generating html inside for loop

I'm using this jquery validation: http://www.runningcoder.org/jqueryvalidation/
It works perfectly but if I generate my code dynamically with javascript, if one of the input fails the data-validation, the error message will appear in all inputs.
Is there a way to fix this?
for (var i = 0; i < result.length; i++) {
inputs += '<div class="input-group bottom15"><span class="input-group-addon">' + (i + 1) + '</span>' +
'<input type="text" class="form-control" placeholder="Insert the description for ' + result[i] + '" name="paramDescriptions" id="paramName' + (i + 1) + '"' +
'data-validation-message="The description must be between 2 and 25 characters. No special characters allowed."\n' +
'data-validation="[L>=2, L<=25, MIXED]" required></div>';
}
The code above generates...
<div id="inputDiv" class="col-sm-10">
<div class="input-group bottom15"><span class="input-group-addon">1</span><input type="text" class="form-control" placeholder="Insert the description for FREQUENCY" name="paramDescriptions" id="paramName1" data-validation-message="The description must be between 2 and 25 characters. No special characters allowed."
data-validation="[L>=2, L<=25, MIXED]" required=""></div>
<div class="input-group bottom15"><span class="input-group-addon">2</span><input type="hidden" class="form-control" name="paramName" value="DAYS"><input type="text" class="form-control" placeholder="Insert the description for DAYS" name="paramDescriptions" id="paramName2" data-validation-message="The description must be between 2 and 25 characters. No special characters allowed."
data-validation="[L>=2, L<=25, MIXED]" required=""></div>
</div>
The jQuery form Validation looks for elements using this part of the code:
node.find('input:not([type="submit"]), select, textarea')
so every input field in your example will be checked. However, the error is registered for the field's name attribute:
var inputName = $(input).attr('name')
// ...
registerError(inputName, error[0].replace('$', inputShortName).replace('%', error[1]));
That's the reason you see error message for both fields.
A simple change of the field's name value to a unique value will fix this issue.

vue onclick function inside appended html not working

I'm having problem using #click vue function inside an appended HTML element using a Vue component.
The component have two button to add and remove divs inside a container, as follow:
<div class="col-md-12">
<button class="btn btn-sm btn-warning" #click.prevent.stop="addQuestion()">Add Question</button>
<button class="btn btn-sm btn-danger" #click.prevent.stop="removeQuestion()" v-if="notRemovableQuestion">Remove Question</button>
</div>
addQuestion function is as follow:
addQuestion(){
var newQuestion = '<div class="questionBox col-md-12 f-left p-2 mt-2" style="border:2px solid blue;">' +
'<div class="col-md-11 f-left">' +
'<input type="text" class="form-control" name="domanda" placeholder="Question" v-model="domanda" />' +
'<input type="text" class="form-control" name="question_description" placeholder="Question Description" v-model="question_description" />' +
'<div class="form-check">' +
'<div class="newAnswerActions f-left full-width col-md-12 mb-2 mt-2">' +
'<a class="btn btn-sm btn-warning" #click.native="addAnswer()">Add Answer</a>' +
'<a class="btn btn-sm btn-danger" #click.native="removeAnswer()" v-if="notRemovableAnswer">Remove Answer</a>' +
'</div>' +
'<label class="form-check-label">' +
'<input class="form-check-input" type="radio" name="risposte" id="exampleRadios1" value="">' +
'<input type="text" class="form-control" name="answer" placeholder="Risposta" />' +
'</label>' +
'</div>' +
'</div>' +
'<div class="col-md-1 f-left">' +
'<button class="btn btn-sm btn-success" #click.prevent.stop="removeQuestion()">SAVE</button>' +
'</div>' +
'</div>';
$(".allQuestionContainer").append(newQuestion); }
The new container is successfully appended but the two buttons for Add Answer and Remove Answer, calling #click.native="addAnswer()" and #click.native="removeAnswer()" are not working. I've tried with or without native and anything else, also with js onClick but no luck, the function is never reached and the click event it's not working.
What I'm doing wrong? Any suggestions?
Thanks!
I would avoid the course you are taking and make use of components instead.
Rather than appending HTML to a div, you could create a component which contains the HTML you're currently assigning to newQuestion. That component would then be responsible for dealing with the addQuestion and removeQuestion methods and because it's a component registered with Vue, it'll automatically be reactive.
Once the component is registered you can control whether it's shown by doing something like:
<new-question v-if="showNewQuestion"></new-question>
Then within your addQuestion method you just set this.showNewQuestion = true so that the component will show. showNewQuestion would obviously need to be declared within your data prop and defaulted to false.
I've not gone into great detail about the formation of the component as I don't know if your using vue-loader or not but more information can be found on the Vue Docs Site.

Automatically copy text when clicked on input area (multiple lnputs) Javascript

I'm trying to get input area to copy text when the user clicks on it. The code itself is selecting correct text but when i add copy function it won't copy correct text. Problem is that this is a template which website use to add elements to the website (so multiple submissions will use same code).
echo '<div class="input-group input-group-sm">';
echo '<span class="input-group-addon input-label-' . strtolower($server->status_text) . '"><i class="fa fa-server" aria-hidden="true"></i> ' . $server->status_text . '</span>';
echo '<input type="text" onclick="this.select()" value="' . $server->address . (($server->connection_port != '25565') ? ":" . $server->connection_port : null) . '">';echo '</div>';
Output on site:
<div class="input-group input-group-sm">
<span class="input-group-addon input-label-online"><i class="fa fa-server" aria-hidden="true"></i> Online</span>
<input type="text" onclick="this.select()" class="form-control" value="Server IP">
</div>
Edit: It looks like i will need to do this via button as using "onclick" is crashing my website. Not sure how to do it with button and without some sort of ID system. The servers are listed via "table" if that helps.
This should work for you:
<input type="text" onclick="this.select(); document.execCommand('Copy');" class="form-control" value="Server IP">
The code you were trying has unescaped parentheses.
This works with multiple input elements: https://jsfiddle.net/xx0gs6Lw/
EDIT
That must be only syntax error then, can you post your exact code? It should look something like this:
echo '<input type="text" onclick="this.select(); document.execCommand(\'Copy\');" value="' . $server->address . (($server->connection_port != '25565') ? ":" . $server->connection_port : null) . '">';

AngularJS directives: Substituting attribute values directly into template

I've been trying to develop an AngularJS directive that outputs a labelled form-field.
I'd like to be able to use a tag like the following:
<simpleTextField bind="user.email" label="Email" name="email"
placeholder="Enter email address"></simpleTextField>
This is to produce the following (bootstrap) HTML output:
<div class="form-group">
<label class="col-sm-2 control-label" for="email">Email</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="email"
ng-model="user.email" placeholder="Enter email address">
</div>
</div>
As you can see the attributes include both an attribute that defines a binding and one whose value is to be substituted directly into the template HTML.
I'd like it to be properly encapsulated. In other words, I don't want to have to modify the view's controller in order to accommodate usage of this directive.
None of the examples I've seen satisfy my requirements because (1) they don't substitute the attribute values directly into the template, and/or (2) they rely on the controller of the view in which the directive is being used to be modified.
Please note that I'm new to AngularJS so I may be completely off track here.
I think I have made something that should work.
You can pass in values to directly bind to the template and the directive has no knowledge of the parent's model.
The HTML + directive:
<div ng-controller="MyCtrl">
<label>Parent Scope Email:{{email}}</label></br>
<simple-text-field simple-bind-to="email" simple-label="Email" simple-name="email"
simple-placeholder="Enter email address" simple-dynamic-scope="user.email">
</simple-text-field>
</div>
The directive:
var myApp = angular.module('myApp',[]);
myApp.directive('simpleTextField', function() {
return {
restrict: 'E',
scope: {
simpleBindTo: "=",
simpleLabel: "#simpleLabel",
simpleName: "#simpleName",
simplePlaceholder: "#simplePlaceholder",
},
template: '<div class="form-group">' +
' <label class="col-sm-2 control-label" for="{{simpleName}}">{{simpleLabel}}</label>' +
' <div class="col-sm-10">' +
' <input type="text" class="form-control" name="{{simpleName}}" ' +
' placeholder="{{simplePlaceholder}}" ng-model="simpleBindTo" >' +
' </div>' +
'</div>'
};
});
myApp.controller('MyCtrl', function ($scope) {
$scope.email = '';
});
By using the '=' access modifier, the ng-model can be assigned variable member of the parent scope, without the directive knowing anything about this variable.
Here is a jsfiddle for the above example.

Categories

Resources