Call google.script.run from HTMLService Template - web-services

When i try execute comand
var obj = google.script.run.receitaws(cnpj);
from custom html template form didin't work, return Undefined, but when run this function by spreadsheets work's.
I will post my project below:
I combine many html files to create html struture form.
To join files i use the function include(file)
function include(File) {
var template = HtmlService.createTemplateFromFile(File).evaluate();
Logger.log(template.getContent());
return HtmlService.createHtmlOutput(template.getContent()).getContent();
}
To call my custom html template by function openlink
function openlink() {
var template = HtmlService.createTemplateFromFile('tabs')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(650);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(template, 'Form');
}
File tabs is a html template file
<?!= include('before')?>
<ul id="tabs-form-servico" class="tabs">
<li id="tbulli1" class="tab col s2"><a class="" href="#tab1">1 - Tomador do Serviço</a></li>
<li id="tbulli2" class="tab col s2"><a class="active" href="#tab2">2 - Prestador do Serviço</a></li>
<li id="tbulli3" class="tab col s2 hide">3 - Serviço Executado</li>
<li id="tbulli4" class="tab col s2 hide">4 - Regras Retenção Municipal</li>
<li id="tbulli5" class="tab col s2 hide">5 - Regras Retenção Previdenciario</li>
<li id="tbulli6" class="tab col s2 hide">6 - Regras Retenções Federal</li>
<li id="tbulli7" class="tab col s2 hide">7 - Cálculo Retenções</li>
<li id="tbulli8" class="tab col s2 hide">8 - Pagamento</li>
</ul>
<div id="tab1" class="col s12">Criar</div>
<div id="tab2" class="col s12"><?!= include('prestadorservico')?></div>
<div id="tab3" class="col s12">Teste bem sucedido</div>
<div id="tab4" class="col s12"></div>
<div id="tab5" class="col s12"></div>
<div id="tab6" class="col s12"></div>
<div id="tab7" class="col s12"></div>
<div id="tab8" class="col s12"></div>
<script>
$(document).ready(function(){
$('#tabs-form-servico').tabs({'swipeable': true });
Materialize.updateTextFields();
});
function close() {
google.script.host.close()'
}
</script>
<?!= include('after')?>
File before is a html template file also
<!DOCTYPE html>
<html>
<head>
<base target="_blank">
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!--Import materialize.css-->
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css" media="screen,projection">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
File after is a html template file also
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.10/jquery.mask.min.js"> </script>
<script>
$(document).ready(function() {
$('select').material_select();
$('.tooltipped').tooltip({delay: 50});
});
</script>
</body>
</html>
The problem is here in html template file prestadorservico
<div class="row">
<form class="col s12">
<div class="row">
<div class="input-field col s3">
<input id="cnpj" type="text" class="validate" autofocus>
<label for="cnpj">CNPJ</label>
</div>
<div class="input-field col s1">
<a class="btn-floating tooltipped rounded" onclick="consultacnpj()" data-tooltip="Preenchimento Automático da RF"><i class="material-icons">refresh</i></a>
</div>
<div class="input-field col s8">
<input placeholder="Prestador LTDA" id="contratado_nome" type="text" class="validate">
<label for="contratado_nome">Nome do Contratado</label>
</div>
</div>
<div class="row">
<div class="input-field col s10">
<input value="" id="address" type="text" class="validate">
<label for="address">Endereço</label>
</div>
<div class="input-field col s2">
<input value="" id="number" type="text" class="validate">
<label for="number">Número</label>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<input value="" id="compl" type="text" class="validate">
<label for="compl">Complemento</label>
</div>
<div class="input-field col s6">
<input value="" id="bairro" type="text" class="validate">
<label for="bairro">Bairro</label>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<?!= include('cidades');?>
</div>
<div class="input-field col s6">
<input value="" id="cep" type="text" class="validate">
<label for="cep">CEP</label>
</div>
</div>
<div class="row">
<div class="input-field col s7">
<input id="email" type="email" class="validate">
<label for="email" data-error="wrong" data-success="right">Email</label>
</div>
<div class="input-field col s5">
<input id="phone" type="text" class="validate">
<label for="phone">Telefone</label>
</div>
</div>
<div class="row">
<div class="input-field col s12 m6">
<input value="" id="cnaep" type="text" class="validate">
<label for="cnaep">CNAE Principal</label>
</div>
<div class="input-field col s12 m6">
<input value="" id="cnaes" type="text" class="validate">
<label for="cnaes">CNAE Secundários</label>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<select>
<option value="" disabled selected>Escolha sua opção</option>
<option value="1">Pessoa Física</option>
<option value="2">MEI - Micro Empreendedor Individual</option>
<option value="3">Imunes/Isentas</option>
<option value="4">Cooperativa de Trabalho</option>
<option value="5">Simples Nacional</option>
<option value="6">Lucro Real/Presumido</option>
</select>
<label>Regime Tributário</label>
</div>
<div class="container col s3 offset-s3">
<a class="btn-large waves-effect waves-light right" id="btnnext2" onclick="nextstep()" name="next">Next
<i class="material-icons right">send</i>
</a>
</div>
</div>
</form>
</div>
<div class="divider"> </div>
<?!= include('SimplesReceitaFederal')?>
<script>
function nextstep() {
$('#tbulli3').removeClass('hide');
$('#tabs-form-servico').tabs('select_tab', 'tab3');
}
function consultacnpj(){
var cnpj = $('#cnpj').val().toString();
if (cnpj.length==14){
var obj = google.script.run.receitaws(cnpj); //here i have a problem
$('#contratado_nome').val(obj);
$('#address').val(obj.logradouro);
$('#number').val(obj.numero);
$('#compl').val(obj.complemento);
$('#bairro').val(obj.bairro);
$('#cep').val(obj.cep);
$('#city').val((obj.municipio + '/' + obj.uf))
var code = google.script.run.codeCNAE(obj.atividade_principal[0].code);
$('#cnaep').val((code + ' - ' + obj.atividade_principal[0].text));
var codes = google.script.run.CNAESecundarios(obj.atividades_secundarias);
$('#cnaes').val(codes);
} else {
Materialize.toast('Preencha um CNPJ valido.', 3000)
}
}
</script>
File cidades is a html template file
<? var data = SpreadsheetApp
.openById('my_id_Sheet')
.getSheetByName('Municipios')
.getRange(3, 4, 5575)
.getValues(); ?>
<select>
<option value="" disabled selected>Escolha a Cidade/UF</option>
<? for (var i = 0; i < data.length; i++) { ?>
<option value="<?!= i ?>"><?!= data[i] ?></option>
<? } ?>
</select>
<label>Cidade/UF</label>
Function.gs codeCNAE()
function codeCNAE(cod){
cod = cod.replace('.', '');
var cods = cod.split('-');
cod = cods[0]+'-'+cods[1]+'/'+cods[2];
return cod;
}
Function.gs CNAESecundarios()
function CNAESecundarios(obj){
var i, codes = "";
for (i in obj) {
if (codes == '') {
codes = '{' + codeCNAE(obj[i].code)
} else {
codes = codes + ', ' + codeCNAE(obj[i].code)
}
codes = codes + ' - ' + obj[i].text
}
codes = codes + '}'
//Logger.log(codes);
return codes;
}
Function.gs receitaws()
function receitaws(cnpj) {
Utilities.sleep(Math.random() * 1000);
var token = "my_id_token";
var url, response, obj;
url = 'http://receitaws.com.br/v1/cnpj/'
+ cnpj;
response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true});
obj = JSON.parse(response);
if (obj.status == "ERROR" && obj.message !="CNPJ inválido") {
Logger.log('Versão Paga');
url = 'https://receitaws.com.br/v1/cnpj/'
+ cnpj
+ "/days/0";
response = UrlFetchApp.fetch(url, {'muteHttpExceptions': true, 'headers': {'Authorization': 'Bearer ' + token}});
obj = JSON.parse(response);
}
return obj;
}

I discovered my problem. In this case I need to run a
.withSuccessHandler(onSuccess)
to get a function return called.
I tried this and it worked.
I change my function consultacnpj() in file prestadorservico
function consultacnpj(){
var cnpj = $('#cnpj').val().toString();
if (cnpj.length==14){
google.script.run
.withSuccessHandler(onSuccessCNPJ)
.withFailureHandler(onFailureCNPJ)
.receitaws(cnpj);
function onFailureCNPJ(error) {
Materialize.toast("ERROR: " + error.message, 3000)
}
function onSuccessCNPJ(obj) {
$('#contratado_nome').val(obj.nome);
$('#address').val(obj.logradouro);
$('#number').val(obj.numero);
$('#compl').val(obj.complemento);
$('#bairro').val(obj.bairro);
$('#cep').val(obj.cep);
$('#city').val((obj.municipio + '/' + obj.uf))
var code = google.script.run
.withSuccessHandler(onSuccessCNAEP)
.withFailureHandler(onFailureCNAEP)
.codeCNAE(obj.atividade_principal[0].code);
function onFailureCNAEP(error) {
Materialize.toast("ERROR: " + error.message, 3000)
}
function onSuccessCNAEP(code) {
$('#cnaep').val(code + ' - ' + obj.atividade_principal[0].text);
};
google.script.run
.withSuccessHandler(onSuccessCNAES)
.withFailureHandler(onFailureCNAES)
.CNAESecundarios(obj.atividades_secundarias);
function onFailureCNAES(error) {
Materialize.toast("ERROR: " + error.message, 3000)
}
function onSuccessCNAES(codes) {
$('#cnaes').val(codes);
}
Materialize.updateTextFields();
Materialize.updateTextFields();
}
} else {
Materialize.toast('Preencha um CNPJ valido.', 3000)
}
}
If anyone have a other tip, please post it.
I'm still learning google-apps-script and javascript.
Thanks!

Related

Django template is rendering in Multi-step form, but context data is not visible

I am working on this problem and somehow resolved it to a very great extent and almost everything is done. But the Django is rendering my template but not the Context.
I don't know why I have checked it by debugging and my context is rendering but not showing in frontend.
On this template, there is a form with 4 fieldset , I am submitting data in 1st fieldset and the dynamically show o/p accordingly on the second fieldset.
I am attaching screenshot to show what is rendering in template(2nd fieldset)
edit:
I have debugged this and in code all is working fine but it is not showing up in fornt-end, I dont know why
#views.py
def createQuotePage(request):
if request.method == "POST":
# Getting all the value
# saving in Table
saveInUnitsTable(-------some code, removed to shorten question ------)
saveInCustomerTable(-------some code, removed to shorten question ------)
saveInInquiryTable(-------some code, removed to shorten question ------)
flight_suggestions =Flight.objects.filter(sourceairportid=1,destinationairportid=51)
context = {'flight_suggestions':flight_suggestions,"test":"99999999999999999999999999999999999999"}
return render(request,"Freight/create_quote.html",context=context) # <-- here is the PROBLEM
if request.method == "GET":
print("========================GET=======================")
context = {'airport_data' : list(Airport.objects.all()),
'commodity_data':list(Commodity.objects.all()),
'customerType_data':list(Entity.objects.all()),
}
return render(request,"Freight/create_quote.html",context=context)
#scripts.js
(function($) {
"use strict";
$.backstretch;
$('#top-navbar-1').on('shown.bs.collapse', function(){
$.backstretch("resize");
});
$('#top-navbar-1').on('hidden.bs.collapse', function(){
$.backstretch("resize");
});
$('.f1 fieldset:first').fadeIn('slow');
$('.f1 .btn-next').on('click', function() {
//
var parent_fieldset = $(this).parents('fieldset');
var next_step = true;
var current_active_step = $(this).parents('.f1').find('.f1-step.active');
var progress_line = $(this).parents('.f1').find('.f1-progress-line');
//
var formData1 = $("#total-shipment-form").serialize();
var formData2 = $("#units-form").serialize();
var formData3 = $("#customerDetailForm").serialize();
var formData4 = $("#firstFieldset").serialize();
var formData = formData1 + '&' +
formData2 + '&' +
formData3 + '&' +
formData4
$.post("",formData)
.done(function(){
//
console.log('Success : ');
// var parent_fieldset = $(this).parents('fieldset');
// var next_step = true;
// var current_active_step = $(this).parents('.f1').find('.f1-step.active');
// var progress_line = $(this).parents('.f1').find('.f1-progress-line');
if( next_step ) {
parent_fieldset.fadeOut(400, function() {
current_active_step.removeClass('active').addClass('activated').next().addClass('active');
bar_progress(progress_line, 'right');
$(this).next().fadeIn();
scroll_to_class( $('.f1'), 20 );
});
}
//
})
.fail(function(){
console.log('Error : ');
});
});
Edited:-
Html template
<fieldset id="secondFieldset">
<div class="form-group select_all_style">
<input class="form-check-input" type="checkbox" value=""
id="select_all">
<label for="select_all" class="font-bold lh-26 fs-14">Select All</label>
</div>
{{test}}
<div class="airline_wrapper check_box_wrapper">
{{test}}
{% for flight in flight_suggestions %}
<div class="col_2 text-center dhl_text ">
<div class="aviation_wrapper">
<div class="aviation_checkbox">
<input class="form-check-input" type="checkbox" value=""
id="flexCheckDefault">
</div>
<div class="d-inline pl_10">
<!-- <p>Expiry Date <span><b>6 Sep 2022</b></span></p> -->
<h4 class="fw-400 fs-28">{{flight.flightcompany}}</h4>
<p>Air Freight</p>
</div>
</div>
</div>
<div class="col_6">
<div class="flight_container text-center">
<i class="fa-solid fa-plane plane_style"></i>
<div class="flight_details"></div>
<div class="flight_content">
<div>
<h4>{{flight.sourceairportid.airportname}}</h4>
<p>{{flight.sourceairportid.cityid.cityname}}</p>
</div>
<div>
<h4>{{flight.destinationairportid.airportname}}</h4>
<p>{{flight.destinationairportid.cityid.cityname}}</p>
</div>
</div>
<hr>
<div class="d-flex">
<div class="flight_sub_text text-left">
<label for="">Transit Time</label>
<h5>-- Hrs</h5>
<h5>{{flight.trasittime}} Hrs</h5>
</div>
</div>
</div>
</div>
<div class="col_3">
<h4 class="text-center reference_text">Past Reference</h4>
<div class="buy_text_wrapper">
<p>Buy Rate</p>
<p>Sell Rate</p>
</div>
<div class="buy_text_wrapper">
<p>USD 5,500.00</p>
<p>USD 7,000.00</p>
</div>
<h5 class="probabilty_text text-center pt-4"><span><i
class="fa-solid fa-arrow-trend-up"></i> 70%</span>
Winnning Probabilty</h5>
</div>
{% endfor %}
</div>
<div class="f1-buttons">
<button class="btn btn-primary btn-next" type="button">Request Better
Rates</button>
</div>
</fieldset>

Do not want to submit form until email and phone are validated - Vue.js 3

I have a form that I am validating - all fields are required. Everything seems to be working except my form submits even when an incorrect phone and email are entered (according to my regex Watch validation). What do I seem to be missing to make sure that the default refresh is prevented if the email and phone are entered incorrectly?
First section is my html form, the second is my Vue.js 3 app code.
<form name="mainForm" #submit="submitForm" method="post">
<div class="row mb-3 gx-2">
<div class="col-md-6">
<label class="form-label aw-font-freight-medium mb-0"
>First Name*</label
>
<input
type="text"
name="firstname"
class="form-control aw-font-freight-medium aw-firstname"
v-model="contact.firstName"
required
/>
</div>
<div class="col-md-6">
<label class="form-label aw-font-freight-medium mb-0"
>Last Name*</label
>
<input
type="text"
name="lastname"
class="form-control aw-font-freight-medium"
v-model="contact.lastName"
required
/>
</div>
</div>
<div class="row mb-3">
<div class="col">
<label class="form-label aw-font-freight-medium mb-0"
>Email Address *</label
>
<input
type="text"
name="email"
class="form-control aw-font-freight-medium"
v-model="contact.email"
required
/>
<small class="form-text text-danger" v-if="msg.email"
>{{msg.email}}</small
>
</div>
</div>
<div class="row mb-3 gx-2">
<div class="col">
<label class="form-label aw-font-freight-medium mb-0"
>Phone*</label
>
<input
type="text"
name="phone"
class="form-control aw-font-freight-medium"
v-model="contact.phone"
required
/>
<small class="form-text text-danger" v-if="msg.phone"
>{{msg.phone}}</small
>
</div>
</div>
<a href="#" target="_blank">
<button type="submit" class="btn aw-bg-orange text-light">
<strong>Download</strong>
</button></a
>
<div>
<small class="form-text text-muted">
<em>* Denotes a required field.</em>
</small>
</div>
</form>
const app = Vue.createApp({
data() {
return {
currentYear: new Date().getFullYear(),
now: new Date().toISOString(),
isSubmitted: false,
msg: [],
contact: {
firstName: "##firstname##",
lastName: "##lastname##",
email: "##email##",
phone: "##phone##",
address: "##address##",
city: "##city##",
state: "##state##",
zip: "##zip##",
checked: false,
},
};
},
watch: {
contact: {
handler(newContact) {
this.validateEmail(newContact.email);
this.validatePhone(newContact.phone);
},
deep: true,
},
},
methods: {
submitForm(e) {
const isValid =
this.contact.firstName ||
this.contact.lastName ||
this.contact.email ||
this.contact.phone;
if (!isValid) {
e.preventDefault();
}
},
validateEmail(value) {
if (
/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,20})$/.test(
value
)
) {
this.msg["email"] = "";
} else {
this.msg["email"] = "Please enter a valid email address.";
}
},
validatePhone(value) {
if (
/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im.test(
value
)
) {
this.msg["phone"] = "";
} else {
this.msg["phone"] = "Please enter a valid, 10 digit phone number.";
}
},
},
});
app.mount("#awApp");
I think your isValid is not working as you expect
const isValid =
this.contact.firstName ||
this.contact.lastName ||
this.contact.email ||
this.contact.phone;
The value of isValid 👆 will return ##firstname##
You should use && instead of || to make sure all values are set. And you may want to include the validators.
You could do that by having validateEmail and validatePhone return a boolean and then you can do
submitForm(e) {
const isValid =
this.contact.firstName &&
this.contact.lastName &&
this.contact.email &&
this.contact.phone &&
this.validateEmail(this.contact.email) &&
this.validatePhone(this.contact.phone);
if (!isValid) {
e.preventDefault();
}
},
update
const app = Vue.createApp({
data() {
return {
currentYear: new Date().getFullYear(),
now: new Date().toISOString(),
isSubmitted: false,
msg: [],
contact: {
firstName: "##firstname##",
lastName: "##lastname##",
email: "##email##",
phone: "##phone##",
address: "##address##",
city: "##city##",
state: "##state##",
zip: "##zip##",
checked: false,
},
};
},
watch: {
contact: {
handler(newContact) {
this.validateEmail(newContact.email);
this.validatePhone(newContact.phone);
},
deep: true,
},
},
methods: {
submitForm(e) {
const isValid =
this.contact.firstName &&
this.contact.lastName &&
this.contact.email &&
this.contact.phone &&
this.validateEmail(this.contact.email) &&
this.validatePhone(this.contact.phone);
console.log(isValid)
if (!isValid) {
e.preventDefault();
}
},
validateEmail(value) {
if (
/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*#[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,20})$/.test(
value
)
) {
this.msg["email"] = "";
return true
} else {
this.msg["email"] = "Please enter a valid email address.";
return false;
}
},
validatePhone(value) {
if (
/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im.test(
value
)
) {
this.msg["phone"] = "";
return true
} else {
this.msg["phone"] = "Please enter a valid, 10 digit phone number.";
return false;
}
},
},
});
app.mount("#app");
<script src="https://unpkg.com/vue#3.0.11/dist/vue.global.prod.js"></script>
<div id="app">
<form name="mainForm" #submit="submitForm" method="post">
<div>
<div>
<label>First Name*</label>
<input
type="text"
name="firstname"
v-model="contact.firstName"
required
/>
</div>
<div>
<label>Last Name*</label>
<input
type="text"
name="lastname"
v-model="contact.lastName"
required
/>
</div>
</div>
<div>
<div>
<label>Email Address *</label>
<input type="text" name="email" v-model="contact.email" required />
<small v-if="msg.email">{{msg.email}}</small>
</div>
</div>
<div>
<div>
<label>Phone*</label>
<input type="text" name="phone" v-model="contact.phone" required />
<small v-if="msg.phone">{{msg.phone}}</small>
</div>
</div>
<a href="#" target="_blank">
<button type="submit">
<strong>Download</strong>
</button></a
>
<div>
<small>
<em>* Denotes a required field.</em>
</small>
</div>
</form>
</div>

Sitecore not pulling through field values

Instead of the field value coming through I get 'No text in the field'. This is for all views that reference a field and isn't hard coded seemingly.
The content is there in the content editor, but not pulling through to the experience editor or the live web view. I've tried rebuilding the link databases, as well as using the GUID in the view to reference the field but no luck fixing this.
For example:
Local
Experience Editor on local
Content editor on local
Live
Experience Editor on live
#using Sitecore.Mvc
#using Sitecore.Data.Items
#using Sitecore.Mvc.Presentation
#model RenderingModel
#{
int counter = 0;
int maxvisible = 6;
// Count can be set in the control properties so the editors can vary the amount of cards showing
if (Html.Sitecore().CurrentRendering.Parameters["Count"] != null)
{
maxvisible = int.Parse(Html.Sitecore().CurrentRendering.Parameters["Count"]);
}
var UniqueName = "";
if (Html.Sitecore().CurrentRendering.Parameters["UniqueName"] != null)
{
UniqueName = Html.Sitecore().CurrentRendering.Parameters["UniqueName"];
}
var cardpanel = "cardpanel" + UniqueName;
UniqueName = "expandbutton" + UniqueName;
Item firstChild = Model.Item.Children[0];
}
<!--Adaptive code (as opposed to Responsive)-->
<!--html code for desktop version-->
<div class="container visible-lg visible-md visible-sm">
<div class="row row-eq-height">
#foreach (Item child in Model.Item.Children)
{
if (#Html.Sitecore().Field("ExcludeFromPage", child).ToString() != "1")
{
if (counter >= maxvisible)
{
if (counter == maxvisible)
{
#:<div class="#cardpanel" style="display: none;">
#:<div class="row-eq-height">
}
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 CardHeightMargin flexbox">
<div class="rcorners1">
<div class="col-xs-12 img-padding cardmobile top">
<div class="#Html.Sitecore().Field("{C63983F3-6ECD-45EA-A1D5-DFB37B366EDD}", child) scale-08"></div>
</div>
<div class="col-xs-12 CardHeight cardmobile bottom">
<h3>#Html.Sitecore().Field("{5787E6DD-A0F2-454F-AC4C-50921D4BBCB3}", child)</h3>
<p>#Html.Sitecore().Field("{1E900F2F-6F68-46B4-A98A-7BDF3CE06C5E}", child)</p>
</div>
</div>
</div>
}
else
{
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 CardHeightMargin flexbox">
<div class="rcorners1">
<div class="col-xs-12 img-padding cardmobile top">
<div class="#Html.Sitecore().Field("{C63983F3-6ECD-45EA-A1D5-DFB37B366EDD}", child) scale-08"></div>
</div>
<div class="col-xs-12 CardHeight cardmobile bottom">
<h3>#Html.Sitecore().Field("{5787E6DD-A0F2-454F-AC4C-50921D4BBCB3}", child)</h3>
<p>#Html.Sitecore().Field("{1E900F2F-6F68-46B4-A98A-7BDF3CE06C5E}", child)</p>
</div>
</div>
</div>
}
counter++;
}
}
#if (counter != 0 && counter > maxvisible)
{
#:</div>
#:</div>
<div class="center-block #UniqueName">
#Html.Sitecore().Field("Expand")
</div>
}
</div>
</div>
<!--html code for mobile version - Carousel-->
<div class="container visible-xs">
<div id=#Model.Item.Children[0].ID.Guid.ToString("N") class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="##Model.Item.Children[0].ID.Guid.ToString("N")" data-slide-to="0" class="active"></li>
#for (int itemcount = 1; itemcount < Model.Item.Children.Count; itemcount++)
{
<li data-target="##Model.Item.Children[0].ID.Guid.ToString("N")" data-slide-to=#itemcount></li>
}
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner m-y-1" role="listbox">
<div class="item mobilecardheight active">
<div class="col-xs-12 img-padding img-div-height">
<div class="#Html.Sitecore().Field("{C63983F3-6ECD-45EA-A1D5-DFB37B366EDD}", firstChild) scale-08"></div>
</div>
<div class="col-xs-12 CardHeight ">
<h3>#Html.Sitecore().Field("{5787E6DD-A0F2-454F-AC4C-50921D4BBCB3}", firstChild)</h3>
<div class="col-xs-12">
<p>#Html.Sitecore().Field("{1E900F2F-6F68-46B4-A98A-7BDF3CE06C5E}", firstChild)</p>
</div>
</div>
</div>
#foreach (Item child in Model.Item.Children)
{
if (child.ID != firstChild.ID)
{
if (#Html.Sitecore().Field("ExcludeFromPage", child).ToString() != "1")
{
<div class="item mobilecardheight">
<div class="col-xs-12 img-padding img-div-height">
<div class="#Html.Sitecore().Field("{C63983F3-6ECD-45EA-A1D5-DFB37B366EDD}", child) scale-08"></div>
</div>
<div class="col-xs-12 CardHeight">
<h3>#Html.Sitecore().Field("{5787E6DD-A0F2-454F-AC4C-50921D4BBCB3}", child)</h3>
<div class="col-xs-12">
<p>#Html.Sitecore().Field("{1E900F2F-6F68-46B4-A98A-7BDF3CE06C5E}", child)</p>
</div>
</div>
</div>
}
}
}
<!-- Left and right controls -->
<a class="left carousel-control" href="##Model.Item.Children[0].ID.Guid.ToString("N")" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="##Model.Item.Children[0].ID.Guid.ToString("N")" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
<!--More button javascript used on the desktop screens-->
#if (counter != 0 && counter > maxvisible)
{
<script>
var acc = document.getElementsByClassName("#UniqueName");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function () {
var panel = this.previousElementSibling;
if (panel != null) {
if (panel.style.display === "block") {
panel.style.display = "none";
this.innerHTML = "<a href='#policies' class='more_link'>Show more</a>";
} else {
panel.style.display = "block";
this.innerHTML = "<a href='#policies' class='more_link'>Show less</a>";
}
}
});
}
</script>
}
This was all working as expected on my local, but I must've changed something elsewhere that caused this. Any ideas?
Can you please add some more Screen shot? am not getting what content you exactly added in content editor.
Your field references look strange to me...
#Html.Sitecore().Field("{5787E6DD-A0F2-454F-AC4C-50921D4BBCB3}", child)
The parameters for #Html.Sitecore().Field() are:
string FieldName
string FieldName, Item item
string FieldName, object parameters
string FieldName, Item item, object parameters
Are your fields literally called "{5787E6DD-A0F2-454F-AC4C-50921D4BBCB3}" or is that just their ID? Your editor screenshot has the fields "CardText", "CardTitle", "CardIcon" and that's what I'd expect to see used instead of the GUIDs:
#Html.Sitecore().Field("CardTitle", child)
No idea why it'd be working on live though if what you showed is also what's deployed.

Django append +1 in template

I have modal that displays uploaded images from ExamFile model that is foreign-key connected to Exam model. In order for lightbox galerry to work i need to specify slide number of each examfile picture, so i need to append 1 for every picture (probably in template?)
i have this script:
{% for file in exam.examfile_set.all %}
<div class="row">
<div class="column">
<img src="{{file.exam_file.url}}" width=60 height="60"
onclick="openModal();currentSlide(//this is where i need to append +1 for every file in exam.examfile_set.all //)"
class="hover-shadow cursor">
</div>
{% endfor %}
<div id="myModal" class="modal">
<span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content">
{% for file in exam.examfile_set.all %}
<div class="mySlides">
<div class="numbertext">1 / 4</div>
<img src="{{file.exam_file.url}}" style="width:100%">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
<div class="caption-container">
<p id="caption"></p>
</div>
</div>
</div>
</div>
<script>
function openModal() {
document.getElementById('myModal').style.display = "block";
}
function closeModal() {
document.getElementById('myModal').style.display = "none";
}
var slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.getElementsByClassName("mySlides");
var dots = document.getElementsByClassName("demo");
var captionText = document.getElementById("caption");
if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i++) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
dots[slideIndex-1].className += " active";
captionText.innerHTML = dots[slideIndex-1].alt;
}
</script>
{% endfor %}
i have posted full code but my problem is in 5th notempty row. Thanks in advance!
You can use built-in forloop.counter variable:
{% for file in exam.examfile_set.all %}
<div class="row">
<div class="column">
<img src="{{ file.exam_file.url }}" width=60 height="60"
onclick="openModal();currentSlide({{ forloop.counter }})"
class="hover-shadow cursor">
</div>
{% endfor %}
More info in the docs: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#for.

Install Opencart store in subdirectory with a Login in the root folder

hope all is well. I am trying to install Opencart (2.0.3) into a subdirectory (Ie. www.website.com/shop/) I want the root URL www.website.com to go to a Login page, where once a user logs in. It will redirect them to the /shop/ portion of the site and allow them to continue their business. I was wondering what the easiest way was to accomplish this. Would I install everything in the root folder, and then modify the .htaccess file along with the config files? Then how would i Make the login files work in the root folder? I tried installing everything first into the subdirectory /shop/... but then I get issues trying to figure out how to get files in the root folder to work.
Thanks in advance!
Yes, need to work with ajax functionality as below. In the index.php insert the following code and replace URL_WITH_SHOP with your urlshop. Then I have taken "shop" as sub-folder installation if it is different then replace "shop" with your sub-folder name:
<script src="shop/catalog/view/javascript/jquery/jquery-2.1.1.min.js" type="text/javascript"></script>
<script src="shop/catalog/view/javascript/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<div class="container">
<div class="row">
<div id="content" class="col-sm-12 ">
<div class="row ">
<div class="col-sm-6" style="margin: 0px auto; float: none;">
<div class="well">
<h2>Returning Customer</h2>
<p><strong>I am a returning customer</strong></p>
<form method="post" enctype="multipart/form-data">
<div class="error"></div>
<div class="form-group">
<label class="control-label" for="input-email">E-Mail Address</label>
<input type="text" name="email" value="" placeholder="E-Mail Address" id="input-email" class="form-control" />
</div>
<div class="form-group">
<label class="control-label" for="input-password">Password</label>
<input type="password" name="password" value="" placeholder="Password" id="input-password" class="form-control" />
</div>
<button type="button" id="button-cart" data-loading-text="Checking login" class="btn btn-primary ">Login</button>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript"><!--
$('#button-cart').on('click', function() {
$.ajax({
url: 'shop/index.php?route=account/loginajax',
type: 'post',
data: $('input[type=\'text\'], input[type=\'password\']'),
dataType: 'json',
beforeSend: function() {
$('#button-cart').button('loading');
},
complete: function() {
$('#button-cart').button('reset');
},
success: function(json) {
$('.alert, .text-danger').remove();
$('.form-group').removeClass('has-error');
if (json['error']) {
$('.error').after('<div class="alert alert-danger has-error">' + json['error'] + '</div>');
}
if (json['success']) {
$('.error').after('<div class="alert alert-success">' + json['success'] + '</div>');
window.location = "URL_WITH_SHOP";
}
}
});
});
//--></script>
Above is the presentation layer, now let's make the logical layer, go to shop/catalog/controller/account and create loginajax.php and paste following code:
<?php
class ControllerAccountLoginAjax extends Controller
{
private $error = array();
public function index()
{
$this->load->model('account/customer');
$json = array();
// Login override for admin users
if (!empty($this->request->get['token'])) {
$this->event->trigger('pre.customer.login');
$this->customer->logout();
$this->cart->clear();
unset($this->session->data['wishlist']);
unset($this->session->data['payment_address']);
unset($this->session->data['payment_method']);
unset($this->session->data['payment_methods']);
unset($this->session->data['shipping_address']);
unset($this->session->data['shipping_method']);
unset($this->session->data['shipping_methods']);
unset($this->session->data['comment']);
unset($this->session->data['order_id']);
unset($this->session->data['coupon']);
unset($this->session->data['reward']);
unset($this->session->data['voucher']);
unset($this->session->data['vouchers']);
$customer_info = $this->model_account_customer->getCustomerByToken($this->request->get['token']);
if ($customer_info && $this->customer->login($customer_info['email'], '', true)) {
// Default Addresses
$this->load->model('account/address');
if ($this->config->get('config_tax_customer') == 'payment') {
$this->session->data['payment_address'] = $this->model_account_address->getAddress($this->customer->getAddressId());
}
if ($this->config->get('config_tax_customer') == 'shipping') {
$this->session->data['shipping_address'] = $this->model_account_address->getAddress($this->customer->getAddressId());
}
$this->event->trigger('post.customer.login');
$this->response->redirect($this->url->link('account/account', '', 'SSL'));
}
}
if ($this->customer->isLogged()) {
$this->response->redirect($this->url->link('account/account', '', 'SSL'));
}
if (!$json) {
$this->load->language('account/login');
$this->document->setTitle($this->language->get('heading_title'));
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) {
$json['success'] = "Successfully logging in! ";
unset($this->session->data['guest']);
// Default Shipping Address
$this->load->model('account/address');
if ($this->config->get('config_tax_customer') == 'payment') {
$this->session->data['payment_address'] = $this->model_account_address->getAddress($this->customer->getAddressId());
}
if ($this->config->get('config_tax_customer') == 'shipping') {
$this->session->data['shipping_address'] = $this->model_account_address->getAddress($this->customer->getAddressId());
}
// Add to activity log
$this->load->model('account/activity');
$activity_data = array(
'customer_id' => $this->customer->getId(),
'name' => $this->customer->getFirstName() . ' ' . $this->customer->getLastName()
);
$this->model_account_activity->addActivity('login', $activity_data);
}
else{
$json['error'] = $this->language->get('error_login');
}
$data['breadcrumbs'] = array();
$data['breadcrumbs'][] = array(
'text' => $this->language->get('text_home'),
'href' => $this->url->link('common/home')
);
$data['breadcrumbs'][] = array(
'text' => $this->language->get('text_account'),
'href' => $this->url->link('account/account', '', 'SSL')
);
$data['breadcrumbs'][] = array(
'text' => $this->language->get('text_login'),
'href' => $this->url->link('account/login', '', 'SSL')
);
$data['heading_title'] = $this->language->get('heading_title');
$data['text_new_customer'] = $this->language->get('text_new_customer');
$data['text_register'] = $this->language->get('text_register');
$data['text_register_account'] = $this->language->get('text_register_account');
$data['text_returning_customer'] = $this->language->get('text_returning_customer');
$data['text_i_am_returning_customer'] = $this->language->get('text_i_am_returning_customer');
$data['text_forgotten'] = $this->language->get('text_forgotten');
$data['entry_email'] = $this->language->get('entry_email');
$data['entry_password'] = $this->language->get('entry_password');
$data['button_continue'] = $this->language->get('button_continue');
$data['button_login'] = $this->language->get('button_login');
if (isset($this->error['warning'])) {
$data['error_warning'] = $this->error['warning'];
} else {
$data['error_warning'] = '';
}
$data['action'] = $this->url->link('account/login', '', 'SSL');
$data['register'] = $this->url->link('account/register', '', 'SSL');
$data['forgotten'] = $this->url->link('account/forgotten', '', 'SSL');
if (isset($this->session->data['success'])) {
$data['success'] = $this->session->data['success'];
unset($this->session->data['success']);
} else {
$data['success'] = '';
}
if (isset($this->request->post['email'])) {
$data['email'] = $this->request->post['email'];
} else {
$data['email'] = '';
}
if (isset($this->request->post['password'])) {
$data['password'] = $this->request->post['password'];
} else {
$data['password'] = '';
}
} else {
$json['error'] = $this->language->get('error_login');
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
protected function validate() {
$this->event->trigger('pre.customer.login');
// Check how many login attempts have been made.
$login_info = $this->model_account_customer->getLoginAttempts($this->request->post['email']);
if ($login_info && ($login_info['total'] >= $this->config->get('config_login_attempts')) && strtotime('-1 hour') < strtotime($login_info['date_modified'])) {
$this->error['warning'] = $this->language->get('error_attempts');
}
// Check if customer has been approved.
$customer_info = $this->model_account_customer->getCustomerByEmail($this->request->post['email']);
if ($customer_info && !$customer_info['approved']) {
$this->error['warning'] = $this->language->get('error_approved');
}
if (!$this->error) {
if (!$this->customer->login($this->request->post['email'], $this->request->post['password'])) {
$this->error['warning'] = $this->language->get('error_login');
$this->model_account_customer->addLoginAttempt($this->request->post['email']);
} else {
$this->model_account_customer->deleteLoginAttempts($this->request->post['email']);
$this->event->trigger('post.customer.login');
}
}
return !$this->error;
}
}
This will help you.
Download files and folders for above codes
Hope it also help you
If you just want the login page then here is the tricks, create index.php or index.html at root folder then paste the following code and change URL_WITH_SHOP in the code with your url with shop like "http://www.example.com/shop" :
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<div class="container">
<div class="row">
<div id="content" class="col-sm-12 ">
<div class="row ">
<div class="col-sm-6" style="margin: 0px auto; float: none;">
<div class="well">
<h2>Returning Customer</h2>
<p><strong>I am a returning customer</strong></p>
<form action="URL_WITH_SHOP/index.php?route=account/login" method="post" enctype="multipart/form-data">
<div class="form-group">
<label class="control-label" for="input-email">E-Mail Address</label>
<input type="text" name="email" value="" placeholder="E-Mail Address" id="input-email" class="form-control" />
</div>
<div class="form-group">
<label class="control-label" for="input-password">Password</label>
<input type="password" name="password" value="" placeholder="Password" id="input-password" class="form-control" />
</div>
<input type="submit" value="Login" class="btn btn-primary" />
</form>
</div>
</div>
</div>
</div>
</div>
</div>
The issue will be if the customer enters wrong username and password then it redirects to the actual login page.