How to solve unexpected number of root elements issue in alpine js? - alpine.js

I am working on functionality in alpine js where I need to add a radio button inside the template tag.
Here is what I am doing.
<div class="customRadioStyle">
<template x-for="name in record.names">
<input type="radio" :value="name.value" :id="name.id">
<label :for="name.id" x-text="name.value"></label>
</template>
</div>
But this code gives me the following error.
Alpine: <template> tag with [x-for] encountered with an unexpected number of root elements. Make sure <template> has a single root element.
Is there any solution for this?
I check this link too but still not able to find a solution for this.
https://github.com/alpinejs/alpine/issues/539
Any help would be appreciated.

Just do what the error says and make sure there's a single element inside the <template>. In you case, you can just add the <input> inside the <label> or wrap them both with a <div>:
window.MyComponent = () => ({
names: [{
id: 'name1',
value: 'Name 1',
}, {
id: 'name2',
value: 'Name 2',
}, {
id: 'name3',
value: 'Name 3',
}],
});
body {
font-family: monospace;
}
label {
display: flex;
align-items: center;
padding: 4px 0;
}
input {
margin: 0 8px 0 0;
}
<div x-data="MyComponent()">
<template x-for="name in names">
<label :for="name.id">
<input type="radio" :value="name.value" :id="name.id" name="radioGroup">
<span x-text="name.value"></span>
</label>
</template>
</div>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js"></script>
Note that in the event handler I'm still calling it e, but in the HTML I've used download($event) instead of download(e).

Related

Dynamically changing class in v-text-field in default slot

I am trying to dynamically change font-size in v-text-field default slot based on the length of the text. However, it seems that v-text-field ignores any specification I specify in the section.
Here is the code
<v-text-field
v-model="attr.name"
hide-details
:readonly="true"
class="core-select"
label="Core Attribute"
>
<template
v-slot:default
>
<div :class="attrNameStyle[0]">
{{ attr.name }}
</div>
</template>
</v-text-field>
I have verified that attrNameStyle[0] is gets set correctly, however that style never gets applied to the default slot. I can change the way input slot looks via this CSS class .v-text-field__slot input { ... } however, I can't update that CSS dynamically.
Thanks for help!
Edit: Adding more context.
.core-select {
width: 180px;
}
.short-core-select {
font-size: 12px;
}
attrNameStyle[0] is set to either '', or 'short-core-select'.
Since v-text-field__slot is working, you could edit that CSS from a higher level.
<v-text-field
v-model="attr.name"
hide-details
hide-details
class="core-select"
:class="attrNameStyle[0]"
label="Core Attribute"
>
<template>
<div>
{{ attr.name }}
</div>
</template>
</v-text-field>
<style>
.short-core-select .v-text-field__slot {
font-size: 12px;
}
</style>

How can I add an md-icon next to an input like in angular material 1?

How can I add md-icon elements next to inputs like in angular material 1 and this screenshot from google contacts:
Google contacts edit form
I know I can use mdPrefix but I like this style better.
Code example:
<md-input-container>
<md-icon mdPrefix>star</md-icon>
<input placeholder="Test" mdInput />
</md-input-container>
The icon inside the input field and I'd like it to be next to it:
Using some css tricks, I was able make something close to the the provided screenshot.
css to position icons:
/deep/ .mat-icon {
color: grey;
width: 24px;
margin: 20px 40px 0 0;
}
html:
<div style="display: flex">
<md-icon >email</md-icon>
<md-input-container >
<input mdInput placeholder="Email">
</md-input-container>
</div>
Code example

data binding in nested angularjs repeater

I have controller as follows:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.questionTypes = [
{display: 'Text', 'name': 'text'},
{display: 'Paragraph', 'name': 'textarea'},
{display: 'Multiple Choice', 'name': 'radio'},
];
$scope.top = {
heading: '',
questions: [
{
tite: 'title 1',
choices: ['']
}
]
};
});
And an HTML body as follows:
<body ng-controller="MainCtrl">
<input ng-model="top.heading" placeholder="heading"/>
<br/>
<div ng-repeat="question in top.questions track by $index">
<select ng-model="question.type" ng-options="c.name as c.display for c in questionTypes"></select>
<div ng-if="question.type == 'radio'">
<div ng-repeat="option in question.choices track by $index">
<input type="text" ng-model="option"/>
<button ng-click="question.choices.push('')" ng-disabled="$index < question.choices.length - 1">Add</button>
<button ng-click="question.choices.splice($index, 1)" ng-disabled="question.choices.length == 1">Del</button>
</div>
</div>
</div>
<pre>{{top | json}}</pre>
</body>
When the user makes the Multiple Choice selection, I want to show a fragment that provides the ability to add various choices. The choices are displayed in repeater.
That all works, but data binding on nested repeater is not working. I assuming this has something to do with scoping, but I can't figure it out.
Any help would be appreciated.
I have created a plunkr at http://plnkr.co/edit/6FxY44HgddRjrLOHlQGF
After fumbling around with this for a while, this is what I did to fix the problem.
I changed:
<input type="text" ng-model="option"/> //after changing model to ng-model
To
<input type="text" ng-model="question.choices[$index]"/>
This allowed the input to reference the parent question object and the choices array on the object instead of referencing the option reference within ng-repeat.

jquery ajax form submit plugin not posting file input

I've got this form:
<form id="imageinputpopup" class=suggestionsubmit style="display: none">
<span>Add a thing!</span><br/>
<label>url: </label><input name="imageurl" type="url"><br/>
<label>file: </label><input name="imagefile" type="file"><br/>
<input type='hidden' name='schoolid' class="schoolid">
<input type="submit" value="Submit">
</form>
And this document.ready:
<script type="text/javascript">
$(document).ready(function() {
$('.schoolid').val(get_gmap_value('school_id'));
$(".allow-submission").live('click', function(){
if($(this).attr('inputtype')=="colorpicker"){
.....
} else if($(this).attr('inputtype')=="image"){
remove_hidden("#imageinputpopup");
add_fieldname($(this), $("#imageinputpopup"));
$("#imageinputpopup").dialog();
} else if($(this).attr('inputtype')=="text"){
....
} else {
//nothing
}
});
$(".suggestionsubmit").submit(function(){
event.preventDefault();
alert($(this).html());
$(this).ajaxSubmit({
url: '/save-school-suggestion/',
type: 'post',
success: function(response){
response = jQuery.parseJSON(response);
// Check for login redirect.
// if ( response.requireLogin ) {
// alert('Sign up or log in to save your answer');
// } else {
$('.suggestionsubmit').dialog('close');
// }
}
});
});
});
function add_fieldname(element, addto){
var elementname = document.createElement('input');
elementname.type = 'hidden';
elementname.name = 'fieldname';
elementname.value = element.attr('fieldname').replace(' ', '_');
$(elementname).addClass('fieldname');
addto.append(elementname);
}
function remove_hidden(element){
$(element+' .fieldname').remove();
}
But the file field isn't showing up server side.
Why?
I found this in the documentation:
Why aren't all my input values posted?
jQuery form serialization aheres closely to the HTML spec. Only successful controls are valid for submission.
But I don't understand why my file control would be invalid.
I have another submission form in a different place on my site that is almost identical and works perfectly...
EDIT: this is the other form that does work (it has some extra stuff in it, but the form tag just has an id, like the problem one, and the input tags are the same).
<form id="photos-submission-form6">
<input type="hidden" name="section" value="photos">
<input type="hidden" name="school" id="photos-submit-school6">
<div style="margin-bottom: .5em">
<p style="position: relative; width:80%; font-size: 14px; display: inline" id="photos-anonymity-header6">Post as: null</p>
<img id="helpicon6" src="/static/img/help-icon.png" style="float: right; cursor: pointer; padding-left:1em;">
<div id="explanation6" style="display: none; padding:1em; background-color:white; border:2px solid gray; position: absolute;z-index:30; right:5px; top:5px">For more posting options, <a id="profilelink6" href="/profile/">fill out your profile</a></div>
</div>
<div id="photos-anonymity-select6" style="margin-bottom: .75em; width:412px" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all"><a class="ui-slider-handle ui-state-default ui-corner-all" href="#" style="left: 100%; "></a></div>
<input type="hidden" id="photos-anonymity-level6" name="anonymity-level" value="username">
<span style="line-height: 40px;">
<label class="photouploadlabel">URL</label><input type="text" name="image-url" style="width: 335px"><br>
<label class="photouploadlabel">File</label><input type="file" name="image-file" style="width: 335px"><br>
<label class="photouploadlabel">Caption</label><input type="text" id="image-caption6" name="image-caption" style="width: 335px; color: rgb(128, 128, 128); ">
</span>
<div style="height: 30px; margin-top: 1em; width: 413px;">
<label id="photos-tagsbutton6" style="margin-right: .5em; cursor: pointer; vertical-align: bottom; float:left; line-height: 1.8em;">Tags</label>
<input id="photos-tagsinput6" style="display: none;" type="text" name="tags">
<button id="send-photos-suggestion6" disabled="" style="float:right; position: relative; bottom: 7px; right: -4px;" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-disabled ui-state-disabled ui-button-text-only" role="button" aria-disabled="true"><span class="ui-button-text">Post</span></button>
</div>
</form>
This is probably not the case but are sure there are no spelling mistake server side? like you would be using $_FILE instead of $_FILES? Could you post the relevant php also?
Also, definitely not an issue but it is recommended to close your input tags, now like this:
<input ... />
Add enctype="multipart/form-data" attribute to your form.
Try to change the type of the input imageurl from url to text:
FROM:
<label>url: </label><input name="imageurl" type="url"><br/>
TO:
<label>url: </label><input name="imageurl" type="text"><br/>
I am not sure, but maybe the jquery plugin fails serializing the form due to invalid type attribute of image_url.
Hey you just forgot to add ---> enctype="multipart/form-data" in the form tag. This will help you out.
I think you have a problem with the binding in javascript not recognising your file.
Try binding your submit trigger event with another live() function
i.e. change
$(".suggestionsubmit").submit(mooFar(e));
to
$(".suggestionsubmit").live('submit', mooFar(e));
...........I was looking in the wrong place in the request for the file.
Server side should have been:
if not s.url_field and 'imagefile' in request.FILES:
s.image_field = request.FILES['imagefile']
instead of
s.image_field = request.POST.get('imagefile', None)
Complete and utter fail on my part.
Make sure the files you're testing aren't outside the max file size, it would be worth setting this in your HTML.
<input type="hidden" name="MAX_FILE_SIZE" value="500" />
Also, testing without the display:none might be worth while until you have the form working; which browser are you testing in?

ajax window doesnt work when tag is deeply nested in the DOM

i am struggeling with a ajax window getting opened in deep nested DOM. I am not that good in jquery so i try to find some help here.
jWindow is supposed to open a new window on click with ajax-content.
For testing i put a Link just under the first DIV. THIS WORKES PERFECT !!!
Then i added some code to generate a TABLE with contains one coloum with a Number which contains the SAME a-tag as the test on top. THIS DOES NOT WORK.
Here is a copy of the DOM(i put horizontal rules around the two a-tags to make it more easy to find them):
<div id="content">
<p>
<a class="get_detail_bill_window" bnr="177" shop="2" href="#">Text Ajax</a>
</p>
<div id="form_selection">
<div class="ui-widget ui-widget-content ui-corner-all" style="padding: 5px; font-size: 1em; width: 1200px;">
<div class="t_fixed_header_main_wrapper ui-widget ui-widget-header ui ui-corner-all">
<div class="t_fixed_header_caption ui-widget-header ui-corner-top">
<div class="t_fixed_header_main_wrapper_child">
<div class="t_fixed_header ui-state-default ui" style="border: medium none; font-weight: normal;">
<div class="headtable ui-state-default" style="margin-right: 15px;">
<div class="body ui-widget-content" style="height: 340px; overflow-y: scroll;">
<div>
<table id="atcs_sort" style="width: 1182px;">
<colgroup>
<tbody>
<tr>
<td class="ui-widget-content">2011-10-16</td>
<td class="numeric ui-widget-content">
<a class="get_detail_bill_window" bnr="341" shop="2" href="#">341</a>
</td>
<td class="numeric ui-widget-content">02:25:08</td>
<td class="numeric ui-widget-content">2011-10-16</td>
If you have a look at these 2 anchors, they are absolute the same. But the one nested in the DOM does not want to work.
Here is the code of the Document ready:
$(".get_detail_bill_window").on({
click: function() {
var shop=$(this).attr('shop');
var bnr=$(this).attr('bnr');
alert("bin im Click - Shop: "+shop+" Billnr: "+bnr);
var a = $.jWindow
({
id: 'detail_bill',
title: 'Details of Bill-Nr.: '+bnr,
minimiseButton: false,
maximiseButton: false,
modal: true,
posx: 450,
posy: 50,
width: 700,
height: 200,
type: 'ajax',
url: 'sge_detail_bill.php?s='+shop+'&bnr='+bnr
}).show();
a.update();
}
});
I tried this to see, if the selector might have a problem:
var pars = $(".get_detail_bill_window");
for( i=0; i<pars.length; i++ ){
alert("Found paragraph: " + pars[i].innerHTML);
}
But i found all(the top sample AND the nested ones) of the a-tags with this class.
So, i am totally lost and desperate. No idea why these nested links are not working.
If somebody have a solution, i would be very greatful.
Many Thanks in advance,
Joe
what is your question put short? rephrase plz. but in case i understood correctly, you want to loop throguh all the elements in your DOM
lets say php made it look like
<.div id='foo'>
<.ul>
<.li><.span id='foo1'><./span><.span id='foo2'><./span><./li>
<.li><./li>
<.li><./li>
<./ul>
<./div>
and to access each of the inner elements do
$('#foo foo1').click(function(){// handler in
$('#foo #foo1').parent().each(function(){// access element, go back to li, loop through all of them
$('#foo2',this).show();// on click of foo1, foo2 will show (as an example)
});
},function(){// handler out
$('#foo #foo1').parent().each(function(){
$('#foo2',this).hide();
});
});
hope this helps somewhat

Resources