angular 5, Keeping value on inputs and adding it to JS object - input

I am making a web tool in angular 5 to help in the creation of new XML.
I am having trouble passing around the values of inputs and keeping them in the same input at the same time.
I Have a form with an event of ngSubmit that uses as a paremeter the reference of an ngForm
<form class="form-group" (ngSubmit)="createSimpleTypeList(f)" #f="ngForm" >
<div class="container">
<div class="row">
<div class="col-sm-12" >
<button class="btn btn-danger flex ">Construir Json!</button>
</div>
</div>
</div>
<hr>
<div class="container" *ngFor="let type of objSimpleType;let i =index">
<hr>
<div class="row">
<div class="col-sm-3">
<input type="text" [(ngModel)]="type.name" name="nameType"/>
<br>
Inserte el nombre del tipo:
</div>
<div class="col-sm-3">
<input type="text" [(ngModel)]="type.type" name="type"/>
<br>
Inserte el tipo:
</div>
<div class="col-sm-2">
<input type="number" [(ngModel)]="type.min" name="min"/>
<br>
Inserte minimo:
</div>
<div class="col-sm-2">
<input type="number" [(ngModel)]="type.max" name="max"/>
<br>
Inserte maximo:
</div>
<div class="col-sm-2">
<input type="checkbox" name="number" /> Numero?
</div>
</div>
</div>
<hr>
</form>
This is the createSimpleTypeList method
console.log(form.value.nameType);
this.objSimpleType.push({
'-name': form.value.nameType,
'xsd:restriction': {
'-base': form.value.type,
'xsd:minLength': {
'-value': form.value.min
},
'xsd:maxLenght': {
'-value': form.value.max
}
}
});
this.typeList.emit(form.value.nameType);
this.sharedNameSpace.emit(this.namespace);
The problem I am having is that I have not found a way to push new items into objSimpleType, without erasing the value of inputs, and if I manage to not erase the value of the inputs then the values of the form wont push.
this is how it looks.how the inputs work right now
This is what I need
How the inputs should be
I am still new to angular, and I would really appreciate the help.

Now that I have looked found the solution, I had two mistakes in the code above.
First my logic was not well executed, I needed to work with unique IDs,and call them dynamically.
Second, I was having trouble to call them , and after reading a lot, I found that I can call the parameters of a Json with brackets[].
"form.value['nameType' + this.i]" --Something like this is what i Needed.

Related

How to use Vuetify for a Keycloak Login theme

I'm still quite new to web development, so there might be some very basic misunderstandings on my part.
What I'm trying to do:
We use Keycloak to manage access to a web app. The app is Vue project using Vuetify. To achieve a unified look, I want to use Vuetify to design the Keycloak theme for the login as well.
Here is the screendesign:
What I've done so far:
I created the folder keycloak/themes/my-theme, and added these files:
I took the two ftl files from the base theme, then I tried to rewrite the login with Vuetify classes.
To do so I inspected the code of the elements I want in the Vuetify docs and worked them into login.ftl. While this did work more or less for the Log In button, it seems to be completely wrong for the inputs.
Here is what it looks like:
The misalignment is probably fixable with a lot of fine tuning, but one thing I don't know what to do about is that the text inputs don't get activated when I click into them.
I'm pretty sure that copying code from the developer tools is the wrong way to do this. Is there any way to actually design a Keycloak theme with Vuetify? Without basically copying the Vuetify code?
Here is the current login.ftl:
<#import "template.ftl" as layout>
<#layout.registrationLayout displayInfo=social.displayInfo displayWide=(realm.password && social.providers??); section>
<#if section = "header">
${msg("loginWelcomeMessage")}
<#elseif section = "form">
<div id="kc-form" <#if realm.password && social.providers??>class="${properties.kcContentWrapperClass!}"</#if>>
<div id="kc-form-wrapper" <#if realm.password && social.providers??>class="${properties.kcFormSocialAccountContentClass!} ${properties.kcFormSocialAccountClass!}"</#if>>
<#if realm.password>
<form id="kc-form-login" onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">
<div class="${properties.kcFormGroupClass!}">
<div class="v-input rom__text--darkblue theme--light v-text-field v-text-field--is-booted v-text-field--enclosed v-text-field--outlined v-text-field--placeholder">
<div class="v-input__control">
<div class="v-input__slot">
<div class="v-input__prepend-inner">
<div class="v-input__icon v-input__icon--prepend-inner"><i aria-hidden="true" class="v-icon notranslate fas fa-user-circle theme--light"></i></div>
</div>
<fieldset aria-hidden="true">
<legend style="width: 188.25px;"><span>​</span></legend>
</fieldset>
<div class="v-text-field__slot">
<label for="username" class="v-label v-label--active" style="left: -28px; right: auto; position: absolute;">
${msg("usernameOrEmail")}
</label>
<#if usernameEditDisabled??>
<input tabindex="1" id="username" placeholder="Ihr Nutzername" type="text" value="${(login.username!'')}" type="text" disabled>
<#else>
<input tabindex="1" id="username" placeholder="Ihr Nutzername" type="text">
</#if>
</div>
</div>
<div class="v-text-field__details">
<div class="v-messages theme--light">
<div class="v-messages__wrapper"></div>
</div>
</div>
</div>
</div>
</div>
<div class="${properties.kcFormGroupClass!}">
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
<input tabindex="2" id="password" class="${properties.kcInputClass!}" name="password" type="password" autocomplete="off" />
</div>
<div class="${properties.kcFormGroupClass!} ${properties.kcFormSettingClass!}">
<div id="kc-form-options">
<#if realm.rememberMe && !usernameEditDisabled??>
<div class="checkbox">
<label>
<#if login.rememberMe??>
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox" checked> ${msg("rememberMe")}
<#else>
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox"> ${msg("rememberMe")}
</#if>
</label>
</div>
</#if>
</div>
<div class="${properties.kcFormOptionsWrapperClass!}">
<#if realm.resetPasswordAllowed>
<span><a tabindex="5" href="${url.loginResetCredentialsUrl}">${msg("doForgotPassword")}</a></span>
</#if>
</div>
</div>
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!} align-center justify-center">
<input type="hidden" id="id-hidden-input" name="credentialId" <#if auth.selectedCredential?has_content>value="${auth.selectedCredential}"</#if>/>
<button tabindex="4" name="login" id="kc-login" type="submit" class=" align-center justify-center v-btn rom__darkblue rom__text--white elevation-2 v-size--large">
<i class="v-icon v-icon--left fas fa-sign-in-alt"></i>
${msg("doLogIn")}
</button>
</div>
</form>
</#if>
</div>
<#if realm.password && social.providers??>
<div id="kc-social-providers" class="${properties.kcFormSocialAccountContentClass!} ${properties.kcFormSocialAccountClass!}">
<ul class="${properties.kcFormSocialAccountListClass!} <#if social.providers?size gt 4>${properties.kcFormSocialAccountDoubleListClass!}</#if>">
<#list social.providers as p>
<li class="${properties.kcFormSocialAccountListLinkClass!}"> <span>${p.displayName}</span></li>
</#list>
</ul>
</div>
</#if>
</div>
<#elseif section = "info" >
<#if realm.password && realm.registrationAllowed && !registrationDisabled??>
<div id="kc-registration">
<span>${msg("noAccount")} <a tabindex="6" href="${url.registrationUrl}">${msg("doRegister")}</a></span>
</div>
</#if>
</#if>
</#layout.registrationLayout>
It looks like you are using Vuetify styles only. I would try to use Vue with the top element:
new Vue({
el: "#kc-form",
vuetify: new Vuetify(),
...
And then I would create all inputs with Vuetify, e.g. username:
<v-text-field label="Username or email" id="username" />
But you need to mimic those original HTML inputs, so you need to add also some parameters, e.g. name - I would use mounted for that - naive implementation:
mounted() {
document.getElementById("username").setAttribute("name", "username")
}
It may need also changes in the layout template and more tweaks to have naive Vuetify feel and full Keycloak functionality. It will be nice if you share your results (even incomplete) on the GitHub.
Proof of concept: https://github.com/jangaraj/vuetify-keycloak-theme/ :

VueJS - v-model in for-loop

I'm trying to build something like the questions in OkayCupid, but all the questions - which are different forms - are located on the same component.
I use an object of questions and 3 possible answers for each question, and I use v-for to loop through the object and create cards with a question, 3 answers with radios, and a submit button.
The problem is that I want to get not only the answer the user chooses, but also the question it belongs to.
Here is my form in the template:
<div class="container">
<div class="row">
<div
class="col-lg-3 col-md-4 col-6"
v-for="(question,index) in questionCollection"
:key="index"
>
<form class="form">
<div class="img-fluid img-thumbnail shadow-lg p-3 mb-5 bg-white rounded">
<!-- <input type="text" :value="question.question" v-model="q" /> -->
<h3 class="d-block mb-4 h-100" alt data-holder-rendered="true">{{ question.question }}</h3>
<div class="card-body container">
<div class="card-text form-check">
<input
class="form-check-input"
type="radio"
name="gridRadios"
id="a1"
:value="question.answer1"
v-model="answer"
/>
<h4 class="font-weight-light" for="a1">{{ question.answer1 }}</h4>
</div>
<div class="card-text form-check">
<input
class="form-check-input"
type="radio"
name="gridRadios"
id="a2"
:value="question.answer2"
v-model="answer"
/>
<h4 class="font-weight-light" for="a2">{{ question.answer2 }}</h4>
</div>
<div class="card-text form-check">
<input
class="form-check-input"
type="radio"
name="gridRadios"
id="a3"
:value="question.answer3"
v-model="answer"
/>
<h4 class="font-weight-light" for="a3">{{ question.answer3 }}</h4>
</div>
</div>
<div class="card-text container">
<small class="text-muted">{{ question.user }}</small>
<button
href="#"
class="btn btn-primary my-3 mx-10 btn float-right shadow-sm rounded"
#click.prevent="answerQuestion"
>Save</button>
</div>
</div>
</form>
</div>
</div>
</div>
And the script:
export default {
name: "questions",
data() {
return {
q: null,
answer: null
};
},
}
As you can see, at the beginning of the form, I tried to get the question element using v-model in a "fake" input, but it gives me an error that it's conflicted with the v-bind of the value (the question) I want to grab. Of course, I can't use v-model on the headline itself because Vue allows to use it only on inputs.
I've tried to change the v-model into v-model="questionCollection[index].question, but then I have no idea how to get it in the script and, let's say, log it to the console with the corresponding answer.
One way to handle this is to submit the question and answer together in the Save button's click-handler. That is, change answerQuestion() to receive question (the iterator variable in v-for) and answer, and update the Save button's click handler in the template to pass those two variables:
// template
<div v-for="(question, index) in questionCollection">
...
<button #click.prevent="answerQuestion(question, answer)">Save</button>
</div>
// script
answerQuestion(question, answer) {
console.log({ question, answer })
}
demo

How to make gmail like search box with bootstrap

I'm trying to implement input field with additional options similar to gmail search box. You can see it on the screenshots below.
When you click on a caret sign then additional form is shown up:
Currently, I'm struggling with making a nice looking form shown after clicking on the caret sign. Anyone knows how to achieve that with Bootstrap?
Here is a jsfiddle link:
https://jsfiddle.net/x1sfs9xb/1/
<div class="container">
<div class="row">
<div class="input-group">
<input type="text" class="form-control">
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></button>
<ul class="dropdown-menu dropdown-menu-right">
<li>
<form action="#" class="form-horizontal">
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="col-sm-3 control-label" for="name">Input 1</label>
<div class="col-sm-9">
<input class="form-control" id="name" name="input1" type="text" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="col-sm-3 control-label" for="name">Input2</label>
<div class="col-sm-9">
<input class="form-control" id="name" name="input2" type="text" />
</div>
</div>
</div>
</div>
<p>
<input class="btn action-button pull-right" name="commit" type="submit" value="Save">
</p>
</form>
</li>
</ul>
<button type="button" class="btn btn-default"><span class="glyphicon glyphicon-search"></span></button>
</div>
</div>
</div><div class="row">
<div class="col-md-12">
<h1>Some content</h1>
</div>
</div>
</div>
You can achieve that by using a little CSS and JS:
CSS (your dropdown menu is relative to input-group-btn so you have to change position of that to static - now your dropdown menu is related to the input-group):
.input-group-btn {
position: static;
}
.dropdown-menu {
left: 0;
}
JS (get width of the input and assign it to your dropdown menu, also change it on browser resize):
var inputWidth = $('.form-control').outerWidth();
$('.dropdown-menu').css('width', inputWidth);
$(window).resize(function () {
inputWidth = $('.form-control').outerWidth();
$('.dropdown-menu').css('width', inputWidth);
});
JSFIDDLE

Two input field next to each other bootstrap 3

I'm new to bootstrap and have a problem placing two input fields next to each other. I've searched on the internet (and bootstrap.com), but couldn't find the anser.
Code:
Result. But I need the input fields and button next to each other in one row:
I tried using columns... didn't work
You can follow : Display two fields side by side in a Bootstrap Form
<div class="input-group">
<input type="text" class="form-control" placeholder="Start"/>
<span class="input-group-addon">-</span>
<input type="text" class="form-control" placeholder="End"/>
You can try below code
<div class="container content">
<div class='row'>
<form role="form" class="form-horizontal" method="post">
<div class='col-xs-12 col-sm-4'>
<div class="form-group">
<input class="form-control" name="" placeholder="Search from this date">
</div>
</div>
<div class='col-xs-12 col-sm-4'>
<div class="form-group">
<input class="form-control" name="" placeholder="Search till this date">
</div>
</div>
<div class='col-xs-12'>
<div class="form-group">
<button class="btn btn-primary">Search</button>
</div>
</div>
<div class='col-xs-12'>
<div class="form-group">
Back
</div>
</div>
</form>
</div>
</div>

Modal dialog with a horizontal form, side by side groups

I'm attempting to render, side by side, form elements within a bootstrap modal dialog. Reason for this is that they're for all intents and purposes the same options, just representing options for different items and the current way it renders for users is basically:
<table>
<tr>
<td><!--Option Group 1--></td>
<td><!--Option Group 2--></td>
<td><!--Option Group 3--></td>
</tr>
</table>
So using the modal dialog example in the Bootstrap 3 documentation combined with the form-horizontal exampl in the Bootstrap 3 documentation plus some use of span to attempt to do a 50% width for each (and hopefully left-to-right tiling of the sections), I came out with:
<div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="addLabel">Title of Dialog</h4>
</div>
<form class="form-horizontal" role="form">
<div class="modal-body">
<div class="row">
<div class="span6">
<div class="form-group">
<label for="inputUser" class="col-sm-1 control-label">User</label>
<div class="col-sm-5">
<input type="text" class="form-control" id="inputUser" value="" disabled="disabled">
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-1 control-label">Password</label>
<div class="col-sm-5">
<input type="password" class="form-control" id="inputPassword3" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-1 col-sm-5">
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
</div>
</div>
</div>
<div class="span6">
<div class="form-group">
<label for="inputUser" class="col-sm-1 control-label">User</label>
<div class="col-sm-5">
<input type="email" class="form-control" id="inputUser" value="" disabled="disabled">
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-1 control-label">Password</label>
<div class="col-sm-5">
<input type="password" class="form-control" id="inputPassword3" placeholder="Password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-1 col-sm-5">
<div class="checkbox">
<label>
<input type="checkbox"> Remember me
</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Add Request</button>
</div>
</form>
</div>
</div>
http://jsfiddle.net/isherwood/3zeMh/
The problem is that somewhere along the way, it is forcing each item to go new line so I have two "forms" that are 50% of the parent width (intentional) that are rendered vertically (not intentional). How can I make the two render side by side?
<div class="span6">
should be
<div class="col-sm-6">
2 times.
http://jsfiddle.net/isherwood/3zeMh/4
It needs a little further cleanup, but that's the primary issue. Here's one possible refinement: http://jsfiddle.net/isherwood/3zeMh/6
I'd probably make the labels wider and keep everything block for mobile, though.